home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1995-12-31 | 119.1 KB | 3,432 lines | [ TEXT/R*ch]
C.S.M.P. Digest Fri, 06 Oct 95 Volume 3 : Issue 115 Today's Topics: 6-byte xDEFs - still a valid technique? Apple Camera API AppleScript recursiveness Code to copy files? Debugging tips? Here's one! GWorlds = 8k overhead? How to Find System Folder on Startup Volume How to convert a raster image into a PICT? How to loop QT movies? Novice Tech Tip #1 - SetRect. Obscure FILEID question Q: FindFolder won't link Resource size limits? [Q] MPW and printf()...Again how do I get char minus any modifier key alterations? The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier (pottier@clipper.ens.fr). The digest is a collection of article threads from the internet newsgroups comp.sys.mac.programmer.help, csmp.tools and csmp.misc. It is designed for people who read news semi-regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you may still be able to post messages to the group by using a mail server like anon.penet.fi (mail help@anon.penet.fi for more information). Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at nef.ens.fr). Article threads are not added to the digest until the last article added to the thread is at least two weeks old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The digest is officially distributed by two means, by email and ftp. If you want to receive the digest by mail, send email to listserv@ens.fr with no subject and one of the following commands as body: help Sends you a summary of commands subscribe csmp-digest Your Name Adds you to the mailing list signoff csmp-digest Removes you from the list Once you have subscribed, you will automatically receive each new issue as it is created. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest. Questions related to the ftp site should be directed to scott.silver@dartmouth.edu. ------------------------------------------------------- >From rdwells@mmm.com (Richard Wells) Subject: 6-byte xDEFs - still a valid technique? Date: 7 Sep 1995 20:28:31 GMT Organization: 3M Company Back in the olden days, before Apple and IBM were on speaking terms and when Copland was most famous as a composer, there was a technique that some of us used for LDEFs whereby we would add a 6-byte LDEF to the application's resource fork, with the first 2 bytes being a 680x0 JMP instruction and the remaining 4 being garbage. Then before using it we would read in the LDEF, make it non-purgeable, and patch the last 4 bytes to contain a pointer to the "real" entry point for the LDEF, which was a routine in one of our application's code segments. (I'm using LDEF for illustration, even though I think this technique was used for CDEFs, WDEFs, and MDEFs as well.) My questions are: (1) Can this technique be used on a Power Mac, in native mode? I realize that the op-code changes, and that it may have to be an 8-byte (or whatever) resource, but can the basic technique be used after adjusting for these differences? (2) Will Copland disallow this? My guess would be yes, since as the OS becomes more robust, things like writing values into code segments and/or executing data segments become verboten. And, for that matter: (3) Was this ever a good idea? It has the feeling of a really nasty kludge, but boy, was it useful. (The xDEF could access the application's globals (after setting A5?), and it made debugging MUCH easier.) I can't remember where I first heard of the technique, but I think it was an "official" Apple source (e.g. an article in Develop, a Tech Note, or a note from DTS in response to a question I had). Any e-mail responses that do not duplicate posted responses will be summarized. >From rdwells@mmm.com (Richard Wells) Subject: 6-byte xDEFs - still a valid technique? Date: 7 Sep 1995 20:28:31 GMT Organization: 3M Company Back in the olden days, before Apple and IBM were on speaking terms and when Copland was most famous as a composer, there was a technique that some of us used for LDEFs whereby we would add a 6-byte LDEF to the application's resource fork, with the first 2 bytes being a 680x0 JMP instruction and the remaining 4 being garbage. Then before using it we would read in the LDEF, make it non-purgeable, and patch the last 4 bytes to contain a pointer to the "real" entry point for the LDEF, which was a routine in one of our application's code segments. (I'm using LDEF for illustration, even though I think this technique was used for CDEFs, WDEFs, and MDEFs as well.) My questions are: (1) Can this technique be used on a Power Mac, in native mode? I realize that the op-code changes, and that it may have to be an 8-byte (or whatever) resource, but can the basic technique be used after adjusting for these differences? (2) Will Copland disallow this? My guess would be yes, since as the OS becomes more robust, things like writing values into code segments and/or executing data segments become verboten. And, for that matter: (3) Was this ever a good idea? It has the feeling of a really nasty kludge, but boy, was it useful. (The xDEF could access the application's globals (after setting A5?), and it made debugging MUCH easier.) I can't remember where I first heard of the technique, but I think it was an "official" Apple source (e.g. an article in Develop, a Tech Note, or a note from DTS in response to a question I had). Any e-mail responses that do not duplicate posted responses will be summarized. +++++++++++++++++++++++++++ >From Jim.Matthews@dartmouth.edu (Jim Matthews) Date: Fri, 08 Sep 1995 09:05:38 -0500 Organization: Dartmouth College In article <42nklf$q3o@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) wrote: >(1) Can this technique be used on a Power Mac, in native >mode? I realize that the op-code changes, and that it may >have to be an 8-byte (or whatever) resource, but can the >basic technique be used after adjusting for these differences? A slightly different technique, which is actually cleaner, can be used. You don't want to put PPC opcodes in your xDEF resource, since the Toolbox expects to find 68k code there. But you can replace the 6-byte xDEF stub with a 32-byte routine descriptor that points to your native routine. Here are the macros I used to do this in Fetch: #define POWER_LDEF_OFFSET 1000 /* offset to PowerPC LDEF stubs */ #ifdef __powerc #define NATIVE_LDEF_ID(x) (x + POWER_LDEF_OFFSET) #define LDEF_ADDR_OFFSET 20 /* offset into routine desc */ #define FLUSH_LDEF_STUB() /* routine desc is data, no flushing */ #else #define NATIVE_LDEF_ID(x) (x) #define LDEF_ADDR_OFFSET 2 /* offset into jump instruction */ #define FLUSH_LDEF_STUB() if (TrapAvailable(0xA198)) { FlushDataCache(); FlushInstructionCache(); } #endif and the initialization code: h = GetResource('LDEF', NATIVE_LDEF_ID(BOOKMARK_LDEF_ID)); *(long *) (*h + LDEF_ADDR_OFFSET) = (long) BookmarkLDEF; FLUSH_LDEF_STUB(); You can copy the stub resources/routine descriptors out of a copy of Fetch (available for downloading from <ftp://ftp.dartmouth.edu/pub/mac/>). >(2) Will Copland disallow this? My guess would be yes, since >as the OS becomes more robust, things like writing values into >code segments and/or executing data segments become verboten. Copland will support existing xDEFs, so I'd expect these techniques to keep working. The OS will be more robust, but it won't stop you from changing the contents of resources in your own heap. But Copland-savvy apps won't use custom xDEFs, they'll override SOM classes, so the motivation for stub xDEFs will go away. >And, for that matter: > >(3) Was this ever a good idea? I think it was a great idea. What I'd question is the decision to require stand-alone resources for something as simple as drawing list cells. A simple callback would have made everyone's life easier. -- Jim Matthews Dartmouth Software Development <http://www.dartmouth.edu/pages/softdev/> +++++++++++++++++++++++++++ >From owenh@harlequin.com (Owen Hartnett) Date: Fri, 8 Sep 1995 18:08:15 GMT Organization: Harlequin, Inc. In article <42nklf$s13@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) wrote: > > My questions are: > > (1) Can this technique be used on a Power Mac, in native > mode? I realize that the op-code changes, and that it may > have to be an 8-byte (or whatever) resource, but can the > basic technique be used after adjusting for these differences? When I asked this same question a few months back, others pointed me to the NewsWatcher source, which seems to have a PowerPC friendly implementation. > > (2) Will Copland disallow this? My guess would be yes, since > as the OS becomes more robust, things like writing values into > code segments and/or executing data segments become verboten. I certainly hope not, for the following reasons: 1) it would not take too much effort to maintain it the way it is, 2) the advantages of using it are significant and 3) they'd break a whole lotta applications. > > And, for that matter: > > (3) Was this ever a good idea? It has the feeling of a really > nasty kludge, but boy, was it useful. (The xDEF could access > the application's globals (after setting A5?), and it made > debugging MUCH easier.) I can't remember where I first heard > of the technique, but I think it was an "official" Apple source > (e.g. an article in Develop, a Tech Note, or a note from DTS > in response to a question I had). I first heard of it from something Larry Rosenstein posted, who was on the MacApp team at the time. Of course, most Apple folk post personally and do not represent the company. I also heard Mike Kahl, the father of Think C, also recommend it at a BCS meeting way long ago. -Owen +++++++++++++++++++++++++++ >From ari@shore.net (Ari Halberstadt) Date: Fri, 08 Sep 1995 19:11:18 -0400 Organization: North Shore Access/Eco Software, Inc; (info@shore.net) In article <42nklf$s13@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) wrote: >Back in the olden days, before Apple and IBM were on speaking >terms and when Copland was most famous as a composer, there >was a technique that some of us used for LDEFs whereby we >would add a 6-byte LDEF to the application's resource fork, >... Here's some code from a popup CDEF that does not require a separate resource and works with 68K and PPC versions. Similar code can be used for LDEFs. /* Creates a glue handle for 68k or PowerPC. */ void PopupGlueInit(PopupGlueUnion *glue, ProcPtr proc, ProcInfoType info) { #if GENERATINGPOWERPC RoutineDescriptor descriptor = BUILD_ROUTINE_DESCRIPTOR(0, 0); glue->ppc.descriptor = descriptor; glue->ppc.descriptor.routineRecords[0].procInfo = info; glue->ppc.descriptor.routineRecords[0].procDescriptor = proc; #else #pragma unused (info) glue->m68k.jmp = 0x4EF9; glue->m68k.proc = proc; if (TrapAvailable(_HWPriv)) { FlushInstructionCache(); FlushDataCache(); } #endif } Here's how it's used: ... /* allocate glue handle for MDEF */ tmp = NewHandle(sizeof(PatchMenuProcStructure)); if (tmp) { (**popup).menuProc = tmp; HLock(tmp); PopupGlueInit(&(**(PatchMenuProcHandle) tmp).glue, (ProcPtr) PatchMenuProc, uppMenuDefProcInfo); HUnlock(tmp); } ... /* A handle to this structure is installed in the menu's menuProc field. */ typedef struct { PopupGlueUnion glue; /* glue stuff */ Handle proc; /* original MDEF handle */ short width; /* width of menu */ } PatchMenuProcStructure, **PatchMenuProcHandle; /* Menu proc to patch the mSizeMsg, allowing us to set the menu width to include the triangle. This is installed just before calling PopupMenuSelect, and is removed immediately afterwards. */ static pascal void PatchMenuProc(short message, MenuHandle menu, Rect *menuRect, Point hitPt, short *whichItem) { PatchMenuProcHandle patch; SignedByte state; Handle proc; patch = (PatchMenuProcHandle) (**menu).menuProc; proc = (**patch).proc; state = HGetState(proc); MoveHHi(proc); HLock(proc); (**menu).menuProc = proc; CallMenuDefProc((MenuDefProcPtr) *proc, message, menu, menuRect, hitPt, whichItem); (**menu).menuProc = (Handle) patch; if (message == mSizeMsg) (**menu).menuWidth = (**patch).width; HSetState(proc, state); } ... /* patch the menu's mdef to ignore the width calculated by the mSizeMsg message */ oldMenuProc = (**(**popup).menu).menuProc; if ((**popup).menuProc) { PatchMenuProcHandle patch = (PatchMenuProcHandle) (**popup).menuProc; (**(**popup).menu).menuProc = (**popup).menuProc; (**patch).proc = oldMenuProc; (**patch).width = menuWidth; } ... /* restore mdef */ (**(**popup).menu).menuProc = oldMenuProc; -- Ari Halberstadt (ari@shore.net) +++++++++++++++++++++++++++ >From rdwells@mmm.com (Richard Wells) Date: 11 Sep 1995 03:06:43 GMT Organization: 3M Company Jim.Matthews@dartmouth.edu (Jim Matthews) wrote: >In article <42nklf$q3o@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) wrote: > >>(1) Can this technique be used on a Power Mac, in native >>mode? I realize that the op-code changes, and that it may >>have to be an 8-byte (or whatever) resource, but can the >>basic technique be used after adjusting for these differences? > >A slightly different technique, which is actually cleaner, can be used. >You don't want to put PPC opcodes in your xDEF resource, since the Toolbox >expects to find 68k code there. But you can replace the 6-byte xDEF stub >with a 32-byte routine descriptor that points to your native routine. >Here are the macros I used to do this in Fetch: > >[code sample deleted] > >You can copy the stub resources/routine descriptors out of a copy of Fetch >(available for downloading from <ftp://ftp.dartmouth.edu/pub/mac/>). Thanks much for the info and code sample. >>(2) Will Copland disallow this? My guess would be yes, since >>as the OS becomes more robust, things like writing values into >>code segments and/or executing data segments become verboten. > >Copland will support existing xDEFs, so I'd expect these techniques to >keep working. The OS will be more robust, but it won't stop you from >changing the contents of resources in your own heap. But Copland-savvy >apps won't use custom xDEFs, they'll override SOM classes, so the >motivation for stub xDEFs will go away. I guess it's time to start learning a thing or two about SOM. That is, if I can ever put down this facinating OLE reading.... (very (:-)) >>And, for that matter: >> >>(3) Was this ever a good idea? > >I think it was a great idea. What I'd question is the decision to require >stand-alone resources for something as simple as drawing list cells. A >simple callback would have made everyone's life easier. Quite true, but there are quite a few things about the Mac Toolbox that leave quite a bit to be desired. Though it does sound like Apple is finally starting to correct some of them with Copland. (See related thread on Copland robustness.) +++++++++++++++++++++++++++ >From gurgle@apple.com (Pete Gontier) Date: Tue, 12 Sep 1995 19:05:49 -0800 Organization: Apple Computer, Inc. In article <430943$mdm@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) quoted: >>> (2) Will Copland disallow this? My guess would be yes, since >>> as the OS becomes more robust, things like writing values into >>> code segments and/or executing data segments become verboten. If you don't like the idea of self-modifying code, use the 10-byte LDEF trick instead. I believe the instructions go like this: LEA @0,A0 JMP (A0) @0: DC.L 'hack' Your mileage may vary; I've typed this in from memory. Since the "instruction" at the label never gets executed, you can stash the real address in there without flushing the instruction cache or worrying about DTS rousting you out of bed in the middle of the night to answer for your sins. With respect to Copland issues, I would be very surprised if this broke under Copland. Consider most present manager APIs to be reasonably stable. Look for radically new APIs for the Copland-savvy GUI. Well, OK, maybe not radically new. New. :-) If LDEFs were CFM-based, then there'd be something to be concerned about, but they aren't, so there isn't. -- Pete Gontier // Software reenignE Macintosh Developer Technical Support // Apple Computer, Inc. +++++++++++++++++++++++++++ >From david_rehring@gdt.com (David Rehring) Date: Wed, 13 Sep 1995 11:40:32 -0700 Organization: GDT Softworks, Inc. In article <gurgle-1209951905490001@mac69.kip.apple.com>, gurgle@apple.com (Pete Gontier) wrote: > In article <430943$mdm@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) quoted: > > >>> (2) Will Copland disallow this? My guess would be yes, since > >>> as the OS becomes more robust, things like writing values into > >>> code segments and/or executing data segments become verboten. > > If you don't like the idea of self-modifying code, use the 10-byte LDEF > trick instead. I believe the instructions go like this: > > LEA @0,A0 > JMP (A0) > @0: DC.L 'hack' > > Your mileage may vary; I've typed this in from memory. > > Since the "instruction" at the label never gets executed, you can stash > the real address in there without flushing the instruction cache or > worrying about DTS rousting you out of bed in the middle of the night to > answer for your sins. > > With respect to Copland issues, I would be very surprised if this broke > under Copland. Consider most present manager APIs to be reasonably stable. > Look for radically new APIs for the Copland-savvy GUI. Well, OK, maybe not > radically new. New. :-) If LDEFs were CFM-based, then there'd be something > to be concerned about, but they aren't, so there isn't. > > -- > Pete Gontier // Software reenignE > Macintosh Developer Technical Support // Apple Computer, Inc. But, don't most caches load more memory into them than is actually required (like each cache area holds 8 or 16 bytes and is loaded and flushed in one shot). So, depending on where in memory the instructions are, the memory just after the JMP(A0) could have been loaded into the onboard cache and thus would have to be flushed to get the correct value. Of course, this depends on which processor, etc... is currently being used. Or I could be completely wrong (it has happened once or twice, I think)! Later, -- David Rehring Software Engineer GDT Softworks, Inc. And all around wacky guy! +++++++++++++++++++++++++++ >From owenh@harlequin.com (Owen Hartnett) Date: Wed, 13 Sep 1995 17:54:37 GMT Organization: Harlequin, Inc. In article <gurgle-1209951905490001@mac69.kip.apple.com>, gurgle@apple.com (Pete Gontier) wrote: > In article <430943$mdm@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) quoted: > > >>> (2) Will Copland disallow this? My guess would be yes, since > >>> as the OS becomes more robust, things like writing values into > >>> code segments and/or executing data segments become verboten. > > If you don't like the idea of self-modifying code, use the 10-byte LDEF > trick instead. I believe the instructions go like this: > > LEA @0,A0 > JMP (A0) > @0: DC.L 'hack' > > Your mileage may vary; I've typed this in from memory. > > Since the "instruction" at the label never gets executed, you can stash > the real address in there without flushing the instruction cache or > worrying about DTS rousting you out of bed in the middle of the night to > answer for your sins. Except here you have a Mixed Mode context switch if you're on a PowerPC with native code. (2 switches in fact). You'll want to create a native version if performance is even slightly an issue for this feature. -Owen +++++++++++++++++++++++++++ >From Mark Williams <Mark@streetly.demon.co.uk> Date: Wed, 13 Sep 95 09:12:01 GMT Organization: Streetly Software In article <gurgle-1209951905490001@mac69.kip.apple.com>, Pete Gontier writes: > > In article <430943$mdm@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) quoted: > > >>> (2) Will Copland disallow this? My guess would be yes, since > >>> as the OS becomes more robust, things like writing values into > >>> code segments and/or executing data segments become verboten. > > If you don't like the idea of self-modifying code, use the 10-byte LDEF > trick instead. I believe the instructions go like this: > > LEA @0,A0 > JMP (A0) > @0: DC.L 'hack' > > Your mileage may vary; I've typed this in from memory. > > > Since the "instruction" at the label never gets executed, you can stash > the real address in there without flushing the instruction cache or > worrying about DTS rousting you out of bed in the middle of the night to > answer for your sins. As posted, the instruction at the label _does_ get executed. You may find MOVE.L @0,A0 more effective than LEA... :-) - -------------------------------------- Mark Williams<Mark@streetly.demon.co.uk> +++++++++++++++++++++++++++ >From Matt Slot <fprefect@umich.edu> Date: 14 Sep 1995 14:53:45 GMT Organization: University of Michigan Mark Williams, Mark@streetly.demon.co.uk writes: > Pete Gontier writes: > > LEA @0,A0 > > JMP (A0) > > @0: DC.L 'hack' > > As posted, the instruction at the label _does_ get executed. You may find > MOVE.L @0,A0 more effective than LEA... :-) Actually that still has the same problem, since the long is part of the instruction, you will set the address in the data cache, and the wrong value will still be in the instruction cache on an '040. MOVE's and LEA's that work on data labels (offsets) work properly. MOVE's and LEA'S with immediate parameters are kept fully in the instruction cache -- and setting them elsewhere can leave them "stale". Pete Gontier then corrects with the right solution: > LEA @0,A0 > MOVE.L (A0), A0 > JMP (A0) > @0: DC.L 'hack' (Which reminds me of a mistake I just coded... DOH, thanks!) My preferred way to do xDEF stubs follows: 1) Create a 10 byte stub resource for 68K machines (to paraphrase): LEA @0,A0 MOVE.L (A0), A0 JMP (A0) @0: DC.L 0xDEADBEEF 2) Create a second resource that is simply a PPC routine descriptor with the ProcPtr field empty. 3) Create an "installer" function that loads the proper DefProc resource by current ISA and inserts the address of the handler function at the right offset. Remember, neither stub has been loaded into the instruction cache and that inserting the ProcPtr is just changing a data field. You shouldn't have to flush. 4) Let it run... you shouldn't even have to dispose the resource stub, since the proper manager should do it for you. Don't set the resource changed flag! I have been using the GENERATINGPOWERPC flag rather than the GENERATINGCFM to conditionally compile the necessary code: Handle LoadMDEFStub(MenuDefUPP mdefHandler) { Handle mdef; #if !GENERATINGPOWERPC // 68K MDEF stub mdef = Get1Resource('MDEF', 98); #else // PPC MDEF stub mdef = Get1Resource('MDEF', 99); #endif if (! mdef) return(0); #if !GENERATINGPOWERPC // Dont quote me on these constants!!! BlockMove(&mdefHandler, *mdef + 6, sizeof(mdefHandler)); #else BlockMove(&mdefHandler, *mdef + 10, sizeof(mdefHandler)); #endif return(mdef); } I have used similar techniques for MDEFs, INITs, jGNEFilters, and even a DRVR (don't ask!). You should know that 68K-CFM will change how code is passed around on the 68K platform, and that you should be careful when building stubs for it... I have no experience with it. Watch the OpenDoc beta-testers... they'll find alot of broken software. However, since these techniques don't make any assumptions about CFM, just the compiled ISA, they *should* work. Matt +++++++++++++++++++++++++++ >From larson@base.cs.ucla.edu (Christopher Larson) Date: 14 Sep 1995 16:33:13 GMT Organization: UCLA, Computer Science Department In article <david_rehring-1309951140330001@204.239.210.210> david_rehring@gdt.com (David Rehring) writes: >In article <gurgle-1209951905490001@mac69.kip.apple.com>, gurgle@apple.com >(Pete Gontier) wrote: > >> [ snip ] >> If you don't like the idea of self-modifying code, use the 10-byte LDEF >> trick instead. I believe the instructions go like this: >> >> LEA @0,A0 >> JMP (A0) >> @0: DC.L 'hack' >> >> Your mileage may vary; I've typed this in from memory. >> >> Since the "instruction" at the label never gets executed, you can stash >> the real address in there without flushing the instruction cache or >> worrying about DTS rousting you out of bed in the middle of the night to >> answer for your sins. > >But, don't most caches load more memory into them than is actually >required (like each cache area holds 8 or 16 bytes and is loaded and >flushed in one shot). So, depending on where in memory the instructions >are, the memory just after the JMP(A0) could have been loaded into the >onboard cache and thus would have to be flushed to get the correct value. Let's assume a copy-back data cache and a read-only instruction cache (the 'worst case' from a self-modifying code point of view). When you write the jump location into @0, you're writing data (as far as the CPU is concerned), so the new target address will be in the data cache. If there is a copy of the code in the instruction cache, that copy remains unmodified. When the JMP instruction is executed, the instruction itself is read from the instruction cache, but when the dereference of A0 takes place, as far as the CPU is concerned, it's reading data. So the copy of whatever is stored at @0 is read from the data cache, not the instruction cache. Ergo, no problem with stale data. It's certainly possible for the instruction cache to contain bytes which are not instructions, as you point out. However, only bytes which are executed as instructions are read from the instruction cache. So anything that isn't executed as an instruction is just wasted space in the instruciton cache. If the caches are unified, then there is no problem at all, unless you're writing directly into memory from some source which bypasses the cache (like an expansion card, and this problem would exist as well for separate caches). The moral of the story is that unless you're modifying the instructions themselves (not happening in this case), or you're writing to memory from someplace other than the CPU (also not happening in this case), you don't need to flush the instruction cache. --Chris _______________________________________________________________________________ Chris Larson -- Amateur Macintosh Geek, CoBase Research Assistant L.A. Institute of Slowly and Painfully Working Out the Surprisingly Obvious - -------------------------------------+--------------------------------------- (Insert Disclaimer Here) | Who's the man ridin' in the sun? UCLA Bruins--1995 NCAA Men's Basketball| Who's the man with the itchy gun? National Champions (yea!) | Who's the man who kills for fun? Internet: larson@kingston.cs.ucla.edu | Psycho Dad, Psycho Dad, PSYCHO DAD! +++++++++++++++++++++++++++ >From gurgle@apple.com (Pete Gontier) Date: Thu, 14 Sep 1995 13:15:57 -0800 Organization: Apple Computer, Inc. In article <439lg9$h03@delphi.cs.ucla.edu>, larson@base.cs.ucla.edu (Christopher Larson) wrote: > It's certainly possible for the instruction cache to contain bytes which are > not instructions, as you point out. However, only bytes which are executed as > instructions are read from the instruction cache. Thank you thank you thank you. Sometimes I'm not able to follow every can of worms I open to its logical conclusion. (Being here isn't really part of my job -- yet.) To reiterate for those who may have missed it, I posted a correction to the wrong newsgroup recently. Errors compounded with errors. Anyway, here it is: In article <gurgle-1309950939480001@mac758.kip.apple.com>, gurgle@apple.com (Pete Gontier) wrote: > Matthias Neeracher pointed out in email the code I posted has a bug. (You > were warned! :-) Here is a correction: > > LEA @0,A0 ; point to last long word in code resource > MOVE.L (A0),A0 ; get that last long word > JMP (A0) ; phone home > @0: > DC.L 'hack' ; this "instruction" can get stale in the code cache > ; because it will never be executed In article <199509141927261141229@stk.berlin.snafu.de>, stk@berlin.snafu.de (Stefan Kurth) wrote: > What's wrong with > > MOVE.L @0,A0 > JMP (A0) > @0: DC.L 'hack' Nothing's wrong with it. It may even be 10 bytes long as I originally promised. :-) The point is that neither of our examples require instruction modification or cache flushing. Memory only becomes code, as far as the cache is concerned, when it is executed. > Personally, I'm using > > MOVE.L @0,-(A7) > RTS > @0: DC.L 'hack' That's even better because it'll work in contexts where you can't afford to step on a register. -- Pete Gontier // Software reenignE Macintosh Developer Technical Support // Apple Computer, Inc. +++++++++++++++++++++++++++ >From Mark Williams <Mark@streetly.demon.co.uk> Date: Fri, 15 Sep 95 13:41:52 GMT Organization: Streetly Software In article <439flp$guq@srvr1.engin.umich.edu>, Matt Slot writes: > > Mark Williams, Mark@streetly.demon.co.uk writes: > > Pete Gontier writes: > > > LEA @0,A0 > > > JMP (A0) > > > @0: DC.L 'hack' > > > > As posted, the instruction at the label _does_ get executed. You may > find > > MOVE.L @0,A0 more effective than LEA... :-) > > Actually that still has the same problem, since the long is part of the > instruction, you will set the address in the data cache, and the wrong > value will still be in the instruction cache on an '040. > Its not quite the same problem... the code as posted just jumped to @0, which is definitely not going to work. Now even assuming you are right, the code at @0 cant be in the cache (unless it wasnt flushed when the xDEF was loaded... in which case the code wont work anyway), so changing the lea to a move will work. You may of course have problems if you keep changing the xDEF to point at different bits of code. > MOVE's and LEA's that work on data labels (offsets) work properly. MOVE's > and > LEA'S with immediate parameters are kept fully in the instruction cache > -- and > setting them elsewhere can leave them "stale". > LEA's dont access memory (and hence the cache) at all. Now, according to M68040UM/AD, section 4.7.1, The Instruction Cache: "The IU uses the instruction cache to store instruction prefetches as it requests them. Instruction prefetches are normally requested from sequential memory locations except when a change of program flow occurs or when an instruction that modifies the SR is executed...." This is the only reference I can find to what goes through the instruction cache (although i havnt read the book that thoroughly) and it suggests to me that pc relative reads _dont_ go through the instruction cache (but i can see that it would make a lot of sense if they did). Can anyone give a definitive answer to this? On a related note, if you leave the xDEF unlocked between calls, do you need to flush the cache whenever you lock it down and call it, or will the memory manager handle that? What about if you have DetachResource'd the xDEF? - -------------------------------------- Mark Williams<Mark@streetly.demon.co.uk> +++++++++++++++++++++++++++ >From grobbins@znet.com (Grobbins) Date: Sat, 16 Sep 1995 09:58:38 -0700 Organization: Skunkworks In article <95091513415200188@streetly.demon.co.uk>, Mark@streetly.demon.co.uk wrote: >This is the only reference I can find to what goes through the instruction cache (although i havnt >read the book that thoroughly) and it suggests to me that pc relative reads _dont_ go through the >instruction cache (but i can see that it would make a lot of sense if they did). How close in memory data that gets modified and instructions that get executed are is irrelevant ('cept for folks writing ROMable code.) If it's not an executable instruction that is getting altered (like a JMP xxxxxxxx) then everything happens on the data side of the 68K cache and no flushing is needed. So as Gontier advocates, load the destination into an address register and jump through that, or push it on the stack and RTS, and you can ignore cache issues. Remember that cache flushes are extremely expensive these days, so avoid them when possible, and use FlushCodeCacheRange for 68K flushes and MakeDataExecutable for PPC flushes when necessary. >On a related note, if you leave the xDEF unlocked between calls, do you need to flush the cache >whenever you lock it down and call it, or will the memory manager handle that? What about if you >have DetachResource'd the xDEF? For 68K code, the memory manager uses BlockMove to move its blocks, and BlockMove of more than a small number of bytes flushes the caches for the appropriate range, so you never have to worry about 68K code resources. Remember that on PPC machines, the processor caches are irrelevant to 68K code, since 68K code is data to the processor. The DR Emulator caches do need to be flushed like the 68040's caches, however. BlockMove, FlushCodeCacheRange, and the other 68K-related cache flushing routines apply to the DR Emulator but don't have any effect on the PPC processor caches. Let's talk native code resources now. For accelerated resources (PPC code fragments kept in resources) the Code Fragment Manager flushes the code range when preparing a fragment, and it always prepares resource-based fragments before entry on 603e/604 machines (the 601 has a unified data/instruction cache and hence isn't susceptible to problems, and CFM on old machines only re-prepares resource-based fragments that have moved.) At least originally, the 603-based Macs (5200 series and similar) weren't re-preparing accelerated resources if they didn't appear to have moved, so in rare cases an accelerated resource that moved back to its original location before being executed a second time might not be consistent in the 603 instruction cache and could crash. For that reason, it's a good idea to always call MakeDataExecutable on an accelerated resource's code before jumping to it. The system doesn't know about or do anything for native non-CFM code kept in resources, so always call MakeDataExecutable before jumping to those. Grobbins grobbins@znet.com --------------------------- >From rondunn@ibm.net (Ron Dunn) Subject: Apple Camera API Date: 15 Sep 1995 14:29:55 GMT Organization: Systems Renovation P/L I have to come up with an application to be used for gate security at a freight terminal. One of the requirements is to store images of trucks as they enter and leave the terminal. I <was> planning to use video tape. I recently saw a demonstration of the Apple Quicktake 950 camera, where it was connected by a cable to a Power Macintosh. The demonstrator clicked the mouse, the camera took a photograph, and it was downloaded to the software package. This is very similar to my requirement. Is there an API available which supports this camera? If so, I could place numbers of these around the terminal controlled by my program. It could take photos at the appropriate time, download the image, and store it in the database. Ron. +++++++++++++++++++++++++++ >From bc@wetware.com (monsieur HAINEUX) Date: 15 Sep 1995 17:37:17 GMT Organization: GRAFIX::CODERRE In article <43c2l3$2rnm@news-s01.ny.us.ibm.net>, rondunn@ibm.net (Ron Dunn) wrote: | I have to come up with an application to be used for gate security at | a freight terminal. One of the requirements is to store images of | trucks as they enter and leave the terminal. I <was> planning to | use video tape. | | I recently saw a demonstration of the Apple Quicktake 950 camera, where | it was connected by a cable to a Power Macintosh. The demonstrator | clicked the mouse, the camera took a photograph, and it was downloaded | to the software package. | | This is very similar to my requirement. Is there an API available | which supports this camera? If so, I could place numbers of these | around the terminal controlled by my program. It could take photos at | the appropriate time, download the image, and store it in the | database. It's the Quicktake 150, and the API documents are available: "Quicktake Digital Camera Developer Note." Now, I don't exactly know which CD it's on, or where to order it from. +++++++++++++++++++++++++++ >From mpeirce@outpost.peircesw.com (Michael Peirce) Date: Tue, 19 Sep 95 16:07:59 PT Organization: Peirce Software, Inc. In article <bc-1509951037450001@mac877.kip.apple.com> (comp.sys.mac.programmer.help), bc@wetware.com (monsieur HAINEUX) writes: > In article <43c2l3$2rnm@news-s01.ny.us.ibm.net>, rondunn@ibm.net (Ron > Dunn) wrote: > > | I have to come up with an application to be used for gate security at > | a freight terminal. One of the requirements is to store images of > | trucks as they enter and leave the terminal. I <was> planning to > | use video tape. > | > | I recently saw a demonstration of the Apple Quicktake 950 camera, where > | it was connected by a cable to a Power Macintosh. The demonstrator > | clicked the mouse, the camera took a photograph, and it was downloaded > | to the software package. > | > | This is very similar to my requirement. Is there an API available > | which supports this camera? If so, I could place numbers of these > | around the terminal controlled by my program. It could take photos at > | the appropriate time, download the image, and store it in the > | database. > > It's the Quicktake 150, and the API documents are available: "Quicktake > Digital Camera Developer Note." > > Now, I don't exactly know which CD it's on, or where to order it from. I've seen this API on the latest MacOS SDK. You can control just about every aspect of this camera using the API. Anyone have a QuickTake hooked up the the web? It seems this would be a better solution to net cams than video cameras... hmmm.... :-) -- Michael Peirce mpeirce@peircesw.com Peirce Software Inc. 719 Hibiscus Place, San Jose California 95117 USA voice: +1 408 244 6554, fax: +1 408 244 6882 Makers of Peirce Print Tools, Smoothie, AppSizer, DeskPicture, & ShareDraw <ftp://mirrors.aol.com/pub/info-mac/cfg/app-sizer-22.hqx> <ftp://mirrors.aol.com/pub/info-mac/gui/desk-picture-401.hqx> <ftp://mirrors.aol.com/pub/info-mac/gst/grf/share-draw-20.hqx> +++++++++++++++++++++++++++ >From Binky the Wonderwhorse <binky@mmcorp.com> Date: 20 Sep 1995 16:45:08 GMT Organization: MultiMedia Corporation lo, Well I haven't had any experience of programmming for the QuickTake yet but I have written vidcam code that grabs images and delivers them on the web. I've been successful at doing this (live web video). "It seems this would be a better solution to net cams than video cameras" Bollox, works for me just fine. Binky +++++++++++++++++++++++++++ >From mpeirce@outpost.peircesw.com (Michael Peirce) Date: Wed, 20 Sep 95 21:00:41 PT Organization: Peirce Software, Inc. In article <43pgek$4vi@news.bt.net> (comp.sys.mac.programmer.help), Binky the Wonderwhorse <binky@mmcorp.com> writes: > lo, > > Well I haven't had any experience of programmming for the QuickTake yet > but I have written vidcam code that grabs images and delivers them on the > web. I've been successful at doing this (live web video). > > "It seems this would be a better solution to net cams than video cameras" > > Bollox, works for me just fine. What I mean is cheaper. You can pick up QuickTake 100's cheap - and there is no need for a digitizer card. The API is easy to deal with too. -- Michael Peirce mpeirce@peircesw.com Peirce Software Inc. 719 Hibiscus Place, San Jose California 95117 USA voice: +1 408 244 6554, fax: +1 408 244 6882 Makers of Peirce Print Tools, Smoothie, AppSizer, DeskPicture, & ShareDraw <ftp://mirrors.aol.com/pub/info-mac/cfg/app-sizer-22.hqx> <ftp://mirrors.aol.com/pub/info-mac/gui/desk-picture-401.hqx> <ftp://mirrors.aol.com/pub/info-mac/gst/grf/share-draw-20.hqx> +++++++++++++++++++++++++++ >From sproul@eos.ap.org (Mark Sproul) Date: Wed, 20 Sep 1995 11:48:43 -0400 Organization: Associated Press R&D In article <43c2l3$2rnm@news-s01.ny.us.ibm.net>, rondunn@ibm.net (Ron Dunn) wrote: > Itrucks as they enter and leave the terminal. I <was> planning to recently saw a demonstration of the Apple Quicktake 950 camera, where > it was connected by a cable to a Power Macintosh. The demonstrator > clicked the mouse, the camera took a photograph, and it was downloaded > to the software package. Its a QuickTake 150, I have written software to drive it, its not hard, Check out my web page at http://pilot.njin.net/~msproul/macintosh/imaging.html The API is avaialbe from APDA and is on the MacOS sdk CD-ROMs. Mark --------------------------- >From st93urnu@post.drexel.edu (Aaron D. Marasco) Subject: AppleScript recursiveness Date: Wed, 13 Sep 1995 19:15:29 -0400 Organization: Drexel University Hi! I would like to know if anyone has any ideas/experience in recursing (sp?) the directory structure of a drive... I'd basically like to get a list of all the folders in an entire drive, similar to MSDOS "/S" parameters... Any ideas on how this can be done? Thanx in advance... -ADM +++++++++++++++++++++++++++ >From plsuh@econ.sas.upenn.edu (Paul L. Suh) Date: Wed, 13 Sep 1995 23:26:28 -0400 Organization: UPenn Grad Econ In article <st93urnu-1309951915290001@sn208014.resnet.drexel.edu>, st93urnu@post.drexel.edu (Aaron D. Marasco) wrote: >Hi! I would like to know if anyone has any ideas/experience in recursing >(sp?) the directory structure of a drive... I'd basically like to get a >list of all the folders in an entire drive, similar to MSDOS "/S" >parameters... Any ideas on how this can be done? Easy enough... There's a Walk Folders command, part of the Jon's Commands OSAX. Alternatively, you can code it in AppleScript by using the Scriptable Finder. Recursion works just fine, although you may want to increase the script's memory partition if you're using it on a large disk. The following is not debugged, but something like it should work: getSubFolders( choose folder ) on getSubFolders( folderToScan ) tell app "Finder" to set foo to all items in folderToScan whose kind is "folder" set subFolders to {} repeat with oneFolder in foo set end of subFolders to getSubFolders(oneFolder) end repeat return foo & subFolders end getSubFolders Be careful of the line wraps that Newswatcher throws in if you use this. I think the OSAX version is preferable, if only because it's _much_ faster. Hope this helps. --Paul -- P |\ / S University of Pennsylvania /---------\ | \ / Graduate Economics |/-------\| | X || . . || My first Macintosh | / \ Paul L. Suh || \_/ || 512K! |/ \ D plsuh@econ.sas.upenn.edu || || +------ Q |\-------/| |---------| |_________| +++++++++++++++++++++++++++ >From Douglas_Shearer@brown.edu (Andrew Shearer) Date: 19 Sep 1995 01:46:04 GMT Organization: Rhode Island Hospital In article <st93urnu-1309951915290001@sn208014.resnet.drexel.edu>, st93urnu@post.drexel.edu (Aaron D. Marasco) wrote: > Hi! I would like to know if anyone has any ideas/experience in recursing > (sp?) the directory structure of a drive... I'd basically like to get a > list of all the folders in an entire drive, similar to MSDOS "/S" > parameters... Any ideas on how this can be done? You could try something like: tell application "Finder" get every folder of entire contents of startup disk end tell or: tell application "Finder" get name of every folder of entire contents of startup disk end tell -- Andrew Shearer Regular email: ashearer@mail.rihosp.edu --------------------------- >From parsoj2@rembrandt.its.rpi.edu (Jeremy Thomas Parsons) Subject: Code to copy files? Date: 11 Sep 1995 12:32:03 GMT Organization: Rensselaer Polytechnic Institute I need some example code on how to go about copying a file. I've looked about some, but not found anything, except a little bit which indicated that it was tricker then it already looked. (While I'm at it, an example thermometer or thermoter cdef would go wonderful with the above as the files I'm looking to copy are huge) -Br'fin +++++++++++++++++++++++++++ >From pandhphot@aol.com (PandH Phot) Date: 12 Sep 1995 16:55:53 -0400 Organization: America Online, Inc. (1-800-827-6364) I had the same problem. I was thrilled to find some useful sample code in Knaster & Rollins' "Macintosh Programming Secrets", 2nd Ed., Chapter 8. The basic idea is: Open DF Get EOF for DF Copy data in buffer size of your choice until EOF Close DF Open RF Get EOF of RF Copy data in buffer until EOF Close RF Get file catalog data from original file Replace catalog data to destination file. Works great! Paul +++++++++++++++++++++++++++ >From ari@shore.net (Ari Halberstadt) Date: Tue, 12 Sep 1995 21:34:23 -0400 Organization: North Shore Access/Eco Software, Inc; (info@shore.net) In article <431a84$9b@usenet.rpi.edu>, jeremy@hp1.ep.cursci.com wrote: >I need some example code on how to go about copying a file. >I've looked about some, but not found anything, except a little >bit which indicated that it was tricker then it already looked. It is trickier. Don't bother thinking about it or trying to do it yourself (I tried and I lost :-). Just go over to Apple's ftp site and grab MoreFiles. >(While I'm at it, an example thermometer or thermoter cdef would >go wonderful with the above as the files I'm looking to copy are >huge) Jim's CDEFs includes a nice thermometer CDEF, among other fun things. You can find it at info-mac mirrors. -- Ari Halberstadt (ari@shore.net, ari@world.std.com) +++++++++++++++++++++++++++ >From Stefan_Buchholtz@midgard.fido.de (Stefan Buchholtz) Date: Wed, 13 Sep 1995 10:45:56 +0200 Organization: Fido.DE domain gateway (IN e.V.) Am 11 Sep 95 schrieb jeremy an All: j> I need some example code on how to go about copying a file. I've j> looked about some, but not found anything, except a little bit which j> indicated that it was tricker then it already looked. This is basically not too difficult - the following code does the trick, but you can probably do a lot better. Some drawbacks: - the file dates (creation & last modification date) are not set. This should be easy to implement. - The routine never calls WaitNextEvent, so all other processes are halted during the copy. This is evil and should never be done in a real application. - It has no progress indicator. - Maybe it could be made faster by using lowlevel calls in asynchronous mode. Especially when running SCSI Manager 4.3 and later. OSErr CopyFile(FSSpecPtr spec, FSSpecPtr destDir) { short readRefNum, writeRefNum; Ptr buf; long count, bufSize; OSErr err; Str255 name; FSSpec destFile; Boolean eofReached; HFileParam pb; pb.ioCompletion = NULL; pb.ioVRefNum = spec->vRefNum; pb.ioFVersNum = 0; pb.ioFDirIndex = 0; pb.ioDirID = spec->parID; pStringCopy(spec->name, name); pb.ioNamePtr = name; err = PBHGetFInfo((HParmBlkPtr)&pb, false); if (err) return err; err = FSpOpenDF(spec, fsRdPerm, &readRefNum); if (err) return err; *name = 1; name[1] = ':'; ConcatString(name, destDir->name); name[++*name] = ':'; ConcatString(name, spec->name); err = FSMakeFSSpec(destDir->vRefNum, destDir->parID, name, &destFile); if (err == noErr) { err = FSpDelete(&destFile); if (err) { FSClose(readRefNum); return err; } } err = FSpCreate(&destFile, pb.ioFlFndrInfo.fdCreator, pb.ioFlFndrInfo.fdType, smSystemScript); if (err) { FSClose(readRefNum); return err; } err = FSpOpenDF(&destFile, fsRdWrPerm, &writeRefNum); if (err) { FSClose(readRefNum); FSpDelete(&destFile); return err; } bufSize = (MaxBlock() / 4096) * 4096 - 8192; buf = NewPtr(bufSize); eofReached = false; while (!eofReached) { count = bufSize; err = FSRead(readRefNum, &count, buf); if (err && err != eofErr) { DisposePtr(buf); FSClose(readRefNum); FSClose(writeRefNum); FSpDelete(&destFile); return err; } else if (err == eofErr) eofReached = true; err = FSWrite(writeRefNum, &count, buf); if (err) { DisposePtr(buf); FSClose(readRefNum); FSClose(writeRefNum); FSpDelete(&destFile); return err; } } FSClose(readRefNum); FSClose(writeRefNum); if (pb.ioFlRLgLen > 0) { // Resource Fork err = FSpOpenRF(spec, fsRdPerm, &readRefNum); if (err) { DisposePtr(buf); return err; } FSpCreateResFile(&destFile, pb.ioFlFndrInfo.fdCreator, pb.ioFlFndrInfo.fdType, smSystemScript); if (err = ResError()) { DisposePtr(buf); FSClose(readRefNum); return err; } err = FSpOpenRF(&destFile, fsRdWrPerm, &writeRefNum); if (err) { DisposePtr(buf); FSClose(readRefNum); return err; } eofReached = false; while (!eofReached) { count = bufSize; err = FSRead(readRefNum, &count, buf); if (err && err != eofErr) { DisposePtr(buf); FSClose(readRefNum); FSClose(writeRefNum); return err; } else if (err == eofErr) eofReached = true; err = FSWrite(writeRefNum, &count, buf); if (err) { DisposePtr(buf); FSClose(readRefNum); FSClose(writeRefNum); return err; } } FSClose(readRefNum); FSClose(writeRefNum); } DisposePtr(buf); } Und tschuess... Stefan +++++++++++++++++++++++++++ >From peter@stairways.com.au (Peter N Lewis) Date: Fri, 15 Sep 1995 00:34:34 +0800 Organization: Stairways Software In article <434s4p$orj@newsbf02.news.aol.com>, pandhphot@aol.com (PandH Phot) wrote: >I had the same problem. I was thrilled to find some useful sample code in >Knaster & Rollins' "Macintosh Programming Secrets", 2nd Ed., Chapter 8. >The basic idea is: Copying a file is impossible to do right. First off, you need to make sure that you don't set the type and creator to anything useful until you've finished copying it (assuming you intend to give time while copying it), since then the user might double click a half copying application/document for example. So you need to set the type/creator to something silly first, and then correct it after you copy the file. Next, you have to remember that if the destination is in a drop folder, then you can't set the type/creator after either fork has any data in it. , So the type and creator have to be set first. Hmm, well, there's contradiction number one. And of course, you have to set the catalog info at the end, so you can set the correct modification date (copying a file does not modify it). Ooops, contradiction number two. Don't forget to touch the parent directory as well. I suggest using MoreFiles - not that I do that myself, but it's a good idea anyway. Enjoy, Peter. -- "there is no significant correlation to violence on TV and agression in daily life" - NHR Broadcasting Culture Research Institute in Tokyo. +++++++++++++++++++++++++++ >From parsoj2@rembrandt.its.rpi.edu (Jeremy Thomas Parsons) Date: 16 Sep 1995 03:46:11 GMT Organization: Rensselaer Polytechnic Institute In article <peter-1509950034340001@zany.peter.com.au>, Peter N Lewis <peter@stairways.com.au> wrote: >I suggest using MoreFiles - not that I do that myself, but it's a good >idea anyway. > >Enjoy, > Peter. >-- >"there is no significant correlation to violence on TV and agression in >daily life" - NHR Broadcasting Culture Research Institute in Tokyo. May I ask as to what MoreFiles is and a full URL to find it? It's been mentioned a few times before, and hinted that it was on one of Apple's sites. However, I've spent some time hunting around www.info.apple.com and have yet to even see anything ... It has my interest, but I just can't find it... Thanks in advance. Br'fin +++++++++++++++++++++++++++ >From tim@dierks.org (Tim Dierks) Date: Sat, 16 Sep 1995 13:35:00 +0100 Organization: Best Internet Communications In article <43dha3$q8l@usenet.rpi.edu>, parsoj2@rembrandt.its.rpi.edu (Jeremy Thomas Parsons) wrote: >In article <peter-1509950034340001@zany.peter.com.au>, >Peter N Lewis <peter@stairways.com.au> wrote: >>I suggest using MoreFiles - not that I do that myself, but it's a good >>idea anyway. >May I ask as to what MoreFiles is and a full URL to find it? MoreFiles is Jim Luther's excellent file manager library which offers a number of utility routines to do things you need to do but which are hard to write. Everyone should have it. <ftp://ftp.info.apple.com/Apple.Support.Area/Developer_Services/Sample_Code/MoreFiles_1.3.1/> Enjoy, - Tim -- Tim Dierks tim@dierks.org --------------------------- >From Darren Giles <mars@netcom.com> Subject: Debugging tips? Here's one! Date: Tue, 19 Sep 1995 00:08:46 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) Always on the lookout for useful debugging tools & tips, I'd love to share ideas with others on the topic. I'll start out by offering a snippet I've found very useful -- hopefully others will do the same. One thing that's really bugged me about MacsBug on PPC is that the stack crawl has become a much less useful tool. The snippet below gives you the ability to keep track of a list of the last significant points your program has visited. It's a list, not a stack, so you can also see patterns of execution. Hardly rocket science, but useful & easy to add. Just call DEBUG_STUFF_INIT at startup, then insert a DEBUG_ENTRY wherever you want. To see what's up, especially during a bad hang, just dm [the address that DEBUG_STUFF_INIT dumped out at startup.] The conditional compilation means that if you turn of debugging in your final build, the release version of the program won't have any of this code in it. [debugstuff.h] #define DB_ROUTINES_NBR_ENTRIES 40 #define DB_ROUTINES_CHARS 16 typedef char db_routine_entry[DB_ROUTINES_CHARS]; #if DEBUGGING void DEBUG_ENTRY (char *txt); void DEBUG_STUFF_INIT (char *title); #else #define DEBUG_ENTRY #define DEBUG_STUFF_INIT #endif [debugstuff.c] /////////////////////////////////////////////////////////////////////// //// #if DEBUGGING void DEBUG_STUFF_INIT (char *title) { OSErr myErr; char txt[256]; long response; if (!MacsBugInstalled()) { hi_notify ("MacsBug is not installed… the debugging log will be inaccessible."); } g_debug_entries= (db_routine_entry*) NewPtrClear ((DB_ROUTINES_NBR_ENTRIES+2) * DB_ROUTINES_CHARS); memset (&g_debug_entries[0], '=', DB_ROUTINES_CHARS); BlockMoveData (title, &g_debug_entries[0], strlen(title)); memset (&g_debug_entries[DB_ROUTINES_NBR_ENTRIES+1], '=', DB_ROUTINES_CHARS); sprintf (txt, "Debugging routine list is at 0x%lx;g", (long) g_debug_entries); c2pstr (txt); DebugStr (txt); } #endif /////////////////////////////////////////////////////////////////////// //// // This leaves a line in the debugging entry log. // For example, important enter/exit points of routines /////////////////////////////////////////////////////////////////////// //// #if DEBUGGING void DEBUG_ENTRY (char *txt) { short len; // Move the previous entries down one BlockMoveData (&g_debug_entries[1], &g_debug_entries[2], (DB_ROUTINES_NBR_ENTRIES-1) * DB_ROUTINES_CHARS); // Clear the new space memset (&g_debug_entries[1], 0, DB_ROUTINES_CHARS); // Copy in the new entry len= strlen (txt); if (len > DB_ROUTINES_CHARS) { len= DB_ROUTINES_CHARS; } BlockMoveData (txt, &g_debug_entries[1], len); } #endif Hope this does someone some good. - Darren ========================================================================== Darren Giles, Technical Director Terran Interactive For info on Cleaner QuickTime compression, visit http://www.terran-int.com +++++++++++++++++++++++++++ >From crawford@scipp.ucsc.edu (Mike Crawford) Date: 19 Sep 1995 02:06:39 GMT Organization: UC Santa Cruz - SCIPP In article <marsDF4LqM.GIy@netcom.com>, Darren Giles <mars@netcom.com> wrote: >Always on the lookout for useful debugging tools & tips, I'd love to share >ideas with others on the topic. I'll start out by offering a snippet I've >found very useful -- hopefully others will do the same. I've just started writing a Web page on debugging tips. I'm hoping to compile most of it either by having people sending me stuff, or by linking to _your_ debugging pages. Here's the URL if you want to look at the one tip I have: http://www.scruznet.com/~crawford/Computers/macsbug.html Some code just like Darren's that I wrote a few years ago allowed me to find some bugs in a real-time networking test tool. The problem was that dropping into the debugger would screw up the two-way communication. Instead I ran a recorder, and would add recorder calls as I narrowed the bug down. -- Mike Crawford One in forty Americans believe that they crawford@scruznet.com have been abducted by aliens. crawford@maxwell.ucsc.edu <-- Finger Me here for PGP Public Key http://www.scruznet.com/~crawford/ (under construction; foundation poured.) +++++++++++++++++++++++++++ >From pchang@csd-d-1.Stanford.EDU (The Weasel) Date: 19 Sep 1995 05:45:47 GMT Organization: Computer Science Department, Stanford University, CA USA. In article <43l8jf$fmv@darkstar.ucsc.edu>, Mike Crawford <crawford@scipp.ucsc.edu> wrote: > Some code just like Darren's that I wrote a few years ago allowed me > to find some bugs in a real-time networking test tool. The problem > was that dropping into the debugger would screw up the two-way > communication. Instead I ran a recorder, and would add recorder calls > as I narrowed the bug down. I recently had an experince like this too where stopping in the debugger was just not possible or practical. Normal logging solutions would not work since every crash caused a complete machine lock-up. The solution, log to the ram disk buffer which is persisten across warm boots. Skanky, but effective. Peter +++++++++++++++++++++++++++ >From grobbins@znet.com (Grobbins) Date: Tue, 19 Sep 1995 00:25:14 -0700 Organization: Skunkworks In article <marsDF4LqM.GIy@netcom.com>, Darren Giles <mars@netcom.com> wrote: >One thing that's really bugged me about MacsBug on PPC is that the stack >crawl has become a much less useful tool. Really? MacsBug 6.5.2 gives quite useful stack crawls on Power Macs. Combined with such recently-improved commands as wh <address> ("where is this") and a slew of other enhancements added in the last year, MacsBug skills are more useful than ever before. Grobbins grobbins@znet.com +++++++++++++++++++++++++++ >From dstone@chem.utoronto.ca (David Stone) Date: Tue, 19 Sep 1995 17:38:01 GMT Organization: University of Toronto Chemistry In article <marsDF4LqM.GIy@netcom.com>, Darren Giles <mars@netcom.com> wrote: > > Always on the lookout for useful debugging tools & tips, I'd love to share > ideas with others on the topic. I'll start out by offering a snippet I've > found very useful -- hopefully others will do the same. > > One thing that's really bugged me about MacsBug on PPC is that the stack > crawl has become a much less useful tool. The snippet below gives you > the ability to keep track of a list of the last significant points your > program has visited. It's a list, not a stack, so you can also see > patterns > of execution. > > Hardly rocket science, but useful & easy to add. Just call > DEBUG_STUFF_INIT > at startup, then insert a DEBUG_ENTRY wherever you want. To see what's > up, especially during a bad hang, just dm [the address that > DEBUG_STUFF_INIT > dumped out at startup.] > > The conditional compilation means that if you turn of debugging in your > final build, the release version of the program won't have any of this > code in it. I've also used conditional compilation to debug serial communications stuff being processed at interrupt time - something like #ifdef DEBUG_MY_ROUTINE #define MAX_BUFFER 10000 char bufffer[MAX_BUFFER]; // or NewPtr it or something long bufCount = 0L; #endif . . . #ifdef DEBUG_MY_ROUTINE if(bufCount < MAX_BUFFER) { bufCount ++; buffer[bufCount] = ch; // ch is a character read/written through serial port } #endif etc. Handy, because you can let it rip for a while to see if there is a consistent pattern in the errors in ch - in my case, a stream of Midi data through a very basic freeware Midi Driver Dave Stone +++++++++++++++++++++++++++ >From Matt Slot <fprefect@umich.edu> Date: 20 Sep 1995 01:41:53 GMT Organization: University of Michigan Darren Giles, mars@netcom.com writes: > One thing that's really bugged me about MacsBug on PPC is that the stack > crawl has become a much less useful tool. The snippet below gives you > the ability to keep track of a list of the last significant points your > program has visited. It's a list, not a stack, so you can also see > patterns of execution. One feature of MacsBug that I like is the "swap" command, which lets you leave a second monitor in the debugger (and punches it out of the desktop). Then, if each DebugStr() ends in ";g" you will get an onscreen log of the last 10 or 15 breaks. I used this to track an elusive bug that would freeze my Mac and trash Macsbug memory... I could see which breakpoint went last. Matt +++++++++++++++++++++++++++ >From dfleck@wacom.com (Dave Fleck) Date: Wed, 20 Sep 1995 09:59:15 -0800 Organization: Wacom Technology Corp. Here's my debugging tip. I do drivers, and you just plain can't set a breakpoint in ADB completion routines (freezes the keyboard so MacsBug is worthless!). So I throw one of the routines below into the routine to see when a piece of code gets executed. What does it do? It "lights up" a bar (length dependant on screen resolution) in the menu bar. So if you DotToggle(300); you get a flashing short line in the menu bar. void DotOn(long where) { long *dot; dot = (long *)(LMGetScrnBase() + where); *dot |= -1; } void DotOff(long where) { long *dot; dot = (long *)(LMGetScrnBase() + where); *dot &= 0; } void DotToggle(long where) { long *dot; dot = (long *)(LMGetScrnBase() + where); *dot ^= -1; } dave - --------------------------------------------------------------- Dave Fleck email:dfleck@wacom.com phone:360-750-8882x154 Wacom Technology Corp. sales@wacom.com 501 S.E. Columbia Shores Blvd, #300 support@wacom.com Vancouver, WA 98661 WWW/FTP:wacom.com - ---------------------------------------------------------------- +++++++++++++++++++++++++++ >From tom@jlc.com (Thomas R. Kimpton) Date: Wed, 20 Sep 1995 12:10:02 -0600 Organization: Jostens Learning Corporation One technique that I have used in the past where dropping into the debugger wasn't an option, and logging wasn't getting flushed in time/took too long, was to create a bunch of cursors numbering 00 - 99, and made a call to set the cursor and return the number of the previous cursor: routine1() { short oldCursor = setDebugCursor(15); ... (void) setDebugCursor(oldCursor); } This way when the machine froze, the cursor would tell me what routine it had frozen in. Tom. -- Tom Kimpton tom@jlc.com Jostens Learning Corporation (801) 223-3228 --------------------------- >From darick@helix.nih.gov (Darick DeHart) Subject: GWorlds = 8k overhead? Date: Fri, 15 Sep 1995 19:49:15 GMT Organization: ICS/NINDS/NIH I've written this program that uses several gworlds. I noticed that no matter what size the actual bit map is, the gworld takes up an additional 8k of space. (For calculating the size of the bitmap I took into account the depth - one byte, and the gworld's rowBytes.) It's not really a problem I just want to know whether I'm doing something wrong or if there really is that much overhead for gworlds. If there is 8k of overhead then what is taking up all that space? Darick -- Darick DeHart darick@helix.nih.gov ICS/NINDS/NIH +++++++++++++++++++++++++++ >From andrewwelc@aol.com (AndrewWelc) Date: 15 Sep 1995 21:03:39 -0400 Organization: America Online, Inc. (1-800-827-6364) > It's not really a problem I just want to know whether I'm doing something > wrong or if there really is that much overhead for gworlds. If there is > 8k of overhead then what is taking up all that space? Nope, that's about right. Regards, Andrew Welch Thaumaturgist Ambrosia Software, Inc. .......... For the latest versions of our software, technical support, and Ambrosia news, stop by and visit the Ambrosia Software, Inc. support forums: America Online ---> Keyword: Ambrosia CompuServe ---> GO word: Ambrosia eWorld --> Shortcut: Ambrosia +++++++++++++++++++++++++++ >From Scott Thompson <sthompson@macromedia.com> Date: 16 Sep 1995 14:57:04 GMT Organization: Macromedia The extra overhead may be accounted for in at least the following: The pixel data (duh) :-) The associated "device" (if a new one was created) The color table The device's inverse table The CGrafPtr and it's associated stuff (regions, patterns, "grafVars" etc.) Junk like that. evidently that all adds up to about 8k... but what's 8k among friends. Scott --------------------------- >From Fang-Pin Chang <fpchang@cs.ucsd.edu> Subject: How to Find System Folder on Startup Volume Date: 21 Sep 1995 21:45:27 GMT Organization: The University of California at San Diego Hi! I am new to this newsgroup. I've been working on a pet project at home to learn more about programming for the Mac, and I am at a point where I am learning about the File Manager. I am at a point where I can recursively visit all directories and get info on all files on all volumes. However, I have a couple of questions that I don't have answers to: 1. How do I determine which is the startup volume? Is the volume that was mounted first always the startup volume? 2. How do I locate the System Folder on a bootable volume? I can search for it exhuastively, but that won't account for multiple folders with the same name. Any help would be much appreciated. Thanks! +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 22 Sep 1995 04:53:29 -0400 Organization: America Online, Inc. (1-800-827-6364) Fang-Pin Chang <fpchang@cs.ucsd.edu> wrote: >1. How do I determine which is the startup volume? Is the >volume that was mounted first always the startup volume? > >2. How do I locate the System Folder on a bootable volume? I >can search for it exhuastively, but that won't account for >multiple folders with the same name. Call FindFolder like this: result = FindFolder(kOnSystemDisk, kSystemFolderType, kCreateFolder, &foundVRefNum, &foundDirID); If result is noErr after calling FindFolder, then foundVRefNum will contain the volume reference number of the boot volume adn foundDirID will contain the directory ID number of the current System Folder. - Jim Luther +++++++++++++++++++++++++++ >From Binky the Wonderwhorse <binky@mmcorp.com> Date: 22 Sep 1995 09:20:43 GMT Organization: MultiMedia Corporation lo, boot volume has volRefNum -1 find system folder by using volRefNum -1 and use a pathname to the system folder. you shouldn't be able to have multiple system folders with the same name. even still, I guess it is possible so try calling OSErr FindFolder(short vRefNum, OSType folderType, Boolean createFolder, short &foundVRefNum, long &foundDirID); using short theVref long theDir iErr = FindFolder(-1, 'macs', FALSE, &theVref, &theDir); Binky --------------------------- >From petrich@netcom.com (Loren Petrich) Subject: How to convert a raster image into a PICT? Date: Fri, 8 Sep 1995 05:45:24 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) I'm trying to write a converter that turns PBMPlus image files into PICT ones. I can read the PBMPlus image OK (a raster image with a simple header), but I have a hard time getting its contents into a PICT file. What I have been doing is something like: RGBColor cval; OpenCPictureParam picdef; [set the image rectangle, etc. from the dimensions in the PBMPlus file's header] pic = OpenCPicture(&picdef); [Loop over coordinates h and v] [set cval to the color value read in from the PBMPlus file] SetCPixel(h,v,&cval); [End loop] ClosePicture(); [code to copy "pic" to the scrap and write it out...] However, it does not seem to produce any picture at all. What's going wrong? -- Loren Petrich Happiness is a fast Macintosh petrich@netcom.com And a fast train Visit my ftp site; its address is (in WWW syntax): ftp://ftp.netcom.com/pub/pe/petrich +++++++++++++++++++++++++++ >From tg3@u.washington.edu (Thurman Gillespy III) Date: Fri, 08 Sep 1995 16:49:23 -0800 Organization: Dept of Radiology, Univ of Washington In article <petrichDEKnzo.JLC@netcom.com>, petrich@netcom.com (Loren Petrich) wrote: > I'm trying to write a converter that turns PBMPlus image files >into PICT ones. I can read the PBMPlus image OK (a raster image with a >simple header), but I have a hard time getting its contents into a PICT >file. What I have been doing is something like: [snip] Make a GWorld. Stuff your pixels into the GWorld pixMap. Then make a Picture by CopyBiting to/from the same GWorld. Make sure the color table of the GWorld is what you want for your PICT. Save the Picture handle as a PICT file. Holler if you need code. -- Thurman Gillespy III | tg3@u.washington.edu Department of Radiology, SB-05 | voice (206)543-3320 University of Washington | fax (206)543-6317 Seattle, WA 98195 | +++++++++++++++++++++++++++ >From petrich@netcom.com (Loren Petrich) Date: Sat, 9 Sep 1995 15:58:19 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) In article <tg3-0809951649230001@gillespy.rad.washington.edu>, Thurman Gillespy III <tg3@u.washington.edu> wrote: >In article <petrichDEKnzo.JLC@netcom.com>, petrich@netcom.com (Loren >Petrich) wrote: >> I'm trying to write a converter that turns PBMPlus image files >>into PICT ones. I can read the PBMPlus image OK (a raster image with a >>simple header), but I have a hard time getting its contents into a PICT >>file. What I have been doing is something like: >[snip] >Make a GWorld. Stuff your pixels into the GWorld pixMap. Then make a Picture >by CopyBiting to/from the same GWorld. Make sure the color table of the >GWorld is what you want for your PICT. Save the Picture handle as a PICT >file. I've created GWorlds for some other stuff, so I'm sure that's no trouble. The problem is with CopyBits -- it will want a destination structure to copy the image to -- and how does one get that from a PicHandle? And I'm sure I'll have to specify the compression to be used in copying to the PicHandle, since I don't think I want to write out an uncompressed image file if I can possibly avoid it. Also, I hope it is not too difficult to specify a palette for a GWorld -- I'd like to do binary and grayscale images that way -- just specify black and white, or 256 grays. -- Loren Petrich Happiness is a fast Macintosh petrich@netcom.com And a fast train Visit my ftp site; its address is (in WWW syntax): ftp://ftp.netcom.com/pub/pe/petrich +++++++++++++++++++++++++++ >From mpeirce@outpost.peircesw.com (Michael Peirce) Date: Fri, 15 Sep 95 15:08:37 PT Organization: Peirce Software, Inc. In article <petrichDEnB17.Hz6@netcom.com> (comp.sys.mac.programmer.help), petrich@netcom.com (Loren Petrich) writes: > I've created GWorlds for some other stuff, so I'm sure that's no > trouble. The problem is with CopyBits -- it will want a destination > structure to copy the image to -- and how does one get that from a PicHandle? While you're recording your picture, just CopyBits from the GWorld pixmap to *itself*. Works great. > And I'm sure I'll have to specify the compression to be used in > copying to the PicHandle, since I don't think I want to write out an > uncompressed image file if I can possibly avoid it. It should just use the standard QuickDraw RLE encoding. > Also, I hope it is not too difficult to specify a palette for a > GWorld -- I'd like to do binary and grayscale images that way -- just > specify black and white, or 256 grays. Simple, when you create your GWorld, pass in a clut. -- Michael Peirce mpeirce@peircesw.com Peirce Software Inc. 719 Hibiscus Place, San Jose California 95117 USA voice: +1 408 244 6554, fax: +1 408 244 6882 Makers of Peirce Print Tools, Smoothie, AppSizer, DeskPicture, & ShareDraw <ftp://mirrors.aol.com/pub/info-mac/cfg/app-sizer-22.hqx> <ftp://mirrors.aol.com/pub/info-mac/gui/desk-picture-401.hqx> <ftp://mirrors.aol.com/pub/info-mac/gst/grf/share-draw-20.hqx> +++++++++++++++++++++++++++ >From petrich@netcom.com (Loren Petrich) Date: Wed, 20 Sep 1995 03:46:01 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) In article <CNjbKKKX.7uhrkk@outpost.peircesw.com>, Michael Peirce <mpeirce@outpost.peircesw.com> wrote: >In article <petrichDEnB17.Hz6@netcom.com> (comp.sys.mac.programmer.help), petrich@netcom.com (Loren Petrich) writes: >> I've created GWorlds for some other stuff, so I'm sure that's no >> trouble. The problem is with CopyBits -- it will want a destination >> structure to copy the image to -- and how does one get that from a PicHandle? >While you're recording your picture, just CopyBits from the GWorld >pixmap to *itself*. Works great. Thanx. It's curious that I was unable to find this trick in _Inside Macintosh_ and a book that was titled (I think) _Programming with QuickDraw_. So what I'll have to do is: Get the image dimensions [I have that] Create a GWorld with its dimensions, presumably as a rectangle with bounds (0,0) to (horiz-1,vert-1) {or is it (horiz,vert)?}; and also with a clut for grayscale or binary (I presume that's easy if one knows the appropriate QuickDraw calls -- all my documentation is at work and I'm at home as I write this) Set every pixel with SetCPixel Create a new picture with OpenCPicture Perform CopyBits of that GWorld's contents to itself. Save that picture. Now that I think about it, I presume it's possible to perform a similar trick for reading in an image. Read in the PICT file Get its bounding rectangle and work out the dimensions Create a GWorld with that bounding rectangle Call DrawPicture() Read off of that GWorld with GetCPixel -- Loren Petrich Happiness is a fast Macintosh petrich@netcom.com And a fast train Visit my ftp site; its address is (in WWW syntax): ftp://ftp.netcom.com/pub/pe/petrich +++++++++++++++++++++++++++ >From mpeirce@outpost.peircesw.com (Michael Peirce) Date: Wed, 20 Sep 95 10:46:39 PT Organization: Peirce Software, Inc. In article <petrichDF6qGp.7to@netcom.com> (petrich@netcom.com), you write: > > Set every pixel with SetCPixel > ... > > Read off of that GWorld with GetCPixel You don't need to use Set/GetCPixel with GWorlds. It's OK to access them directly as memory. I've done this many times and it works fine. No trap overhead as Set/etCPixel does. -- Michael Peirce mpeirce@peircesw.com Peirce Software Inc. 719 Hibiscus Place, San Jose California 95117 USA voice: +1 408 244 6554, fax: +1 408 244 6882 Makers of Peirce Print Tools, Smoothie, AppSizer, DeskPicture, & ShareDraw <ftp://mirrors.aol.com/pub/info-mac/cfg/app-sizer-22.hqx> <ftp://mirrors.aol.com/pub/info-mac/gui/desk-picture-401.hqx> <ftp://mirrors.aol.com/pub/info-mac/gst/grf/share-draw-20.hqx> +++++++++++++++++++++++++++ >From ejensen@server.uwindsor.ca (Erik Jensen) Date: Thu, 21 Sep 1995 14:03:54 GMT Organization: University of Windsor In article <CNjbKKKX.8b8cej@outpost.peircesw.com>, mpeirce@outpost.peircesw.com (Michael Peirce) wrote: >In article <petrichDF6qGp.7to@netcom.com> (petrich@netcom.com), you write: >> >> Set every pixel with SetCPixel >> >... >> >> Read off of that GWorld with GetCPixel > >You don't need to use Set/GetCPixel with GWorlds. It's OK to access >them directly as memory. I've done this many times and it works fine. > >No trap overhead as Set/etCPixel does. > Could someone point me to a code fragment that demonstrates this (being an extreme newbie I haven't done this before)? Are there Color QD calls that access the memory faster or do I read memory directly? Thanks, Erik. __________________________________________________________________________ Erik Jensen ejensen@server.uwindsor.ca Department of Physics University of Windsor __________________________________________________________________________ +++++++++++++++++++++++++++ >From tg3@u.washington.edu (Thurman Gillespy III) Date: Thu, 21 Sep 1995 10:29:42 -0800 Organization: Dept of Radiology, Univ of Washington In article <ejensen-2109951003540001@ejensen.esxf.uwindsor.ca>, ejensen@server.uwindsor.ca (Erik Jensen) wrote: >In article <CNjbKKKX.8b8cej@outpost.peircesw.com>, >mpeirce@outpost.peircesw.com (Michael Peirce) wrote: > >>In article <petrichDF6qGp.7to@netcom.com> (petrich@netcom.com), you write: >>> >>> Set every pixel with SetCPixel >>> >>... >>> >>> Read off of that GWorld with GetCPixel >> >>You don't need to use Set/GetCPixel with GWorlds. It's OK to access >>them directly as memory. I've done this many times and it works fine. >> >>No trap overhead as Set/etCPixel does. >> > >Could someone point me to a code fragment that demonstrates this (being an >extreme newbie I haven't done this before)? Are there Color QD calls that >access the memory faster or do I read memory directly? > >Thanks, >Erik. >__________________________________________________________________________ >Erik Jensen ejensen@server.uwindsor.ca >Department of Physics >University of Windsor >__________________________________________________________________________ This works for me. The code fragment assumes you have a valid GWorld and the xdim and ydim of the image (which is the same as the portRect of the GWorld), and that you have an 8-bit GWorld and 8-bit pixels that you are reading/writing to/from the GWorld. // char *myPixPtr; // long xdim, ydim; // GWorldPtr theGWorld; PixMapHandle pixBaseH = nil; char *wp = nil; long lockPixResult, i, j; Boolean swapMode; short rowBytes; SInt8 mmuMode; /* get handle to pixMap of GWorld */ pixBaseH = theGWorld->portPixMap; // make sure this isn't nil! lockPixResult = LockPixels(pixBaseH); // lock it down // make sure lockPixResult == true ! // switch to 32-bit addressing mode if 32-bit capable // and started in 24 bit mode // version suggested by Mac Programming FAQ swapMode = PixMap32Bit(pixBaseH); // need 32bit addressing? if (swapMode) { // if so, switch into 32 bit mode mmuMode = true32b; SwapMMUMode(&mmuMode); } // calculate the 'extra' bytes at the end of each row in the GWorld rowBytes = (*pixBaseH)->rowBytes; // GWorld rowBtyes rowBytes &= ~0x8000; // mask high bit extraBytes = rowBytes - xdim; // extra bytes at end of each row // now get a pointer to the GWorld pixels wp = (char *)(GetPixBaseAddr(pixBaseH)); // valid 32-bit pointer // make sure wp != nil ! // now read/write to the GWorld pixels, taking care to step over // the 'extra' bytes at the end of each row for (i = 0; i < ydim; i++) { for (j = 0; j < xdim; j++) { // lets assume we are writing to the pixMap *wp++ = *myPixPtr++; } // now step over the extra bytes wp += extraBytes; } if (swapMode) SwapMMUMode(&mmuMode); UnlockPixels(pixBaseH); } /* ImagePixelsToGWorld */ Hope this helps. -- Thurman Gillespy III | tg3@u.washington.edu Department of Radiology, SB-05 | voice (206)543-3320 University of Washington | fax (206)543-6317 Seattle, WA 98195 | --------------------------- >From hunt@scws4.harvard.edu (Timothy Hunt) Subject: How to loop QT movies? Date: 21 Sep 1995 13:46:25 GMT Organization: Harvard University, Cambridge, Massachusetts I would like to know the best way to loop a quicktime movie. I can not seem to find anything in NIM to loop automatically, so maybe my program must restart the movie itself from the beginning when it is done? There is some references to looping in the TimeBase stuff - Does that contain the answer? If that is the case, should I set up some kind of call back to notify me when my movie has finished? Can I restart from such a call back which would probably occur at interupt time? I've also heard that there is some bit that must be set to get smooth looping. Any info here? BTW, I'm actually only playing the sound track of a blank movie to use Quicktime's music. Thanks alot for any help!! -Tim (hunt@fas.harvard.edu) +++++++++++++++++++++++++++ >From "Andrew C. Plotkin" <erkyrath+@CMU.EDU> Date: Thu, 21 Sep 1995 11:27:05 -0400 Organization: Carnegie Mellon, Pittsburgh, PA hunt@scws4.harvard.edu (Timothy Hunt) writes: > I would like to know the best way to loop a quicktime movie. I can not > seem to find anything in NIM to loop automatically, so maybe my program > must restart the movie itself from the beginning when it is done? > There is some references to looping in the TimeBase stuff - Does that > contain the answer? What I do is: tb = GetMovieTimeBase(mov); SetTimeBaseFlags(tb, loopTimeBase); > I've also heard that there is some bit that must be set to get smooth > looping. Any info here? There may be a delay unless you load the entire movie into RAM. That's the only way I know to deal with it. (If there's another, I'd really like to know about it...) --Z "And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..." +++++++++++++++++++++++++++ >From tkmower@sdt.com (Terrence Kelly Mower) Date: Thu, 21 Sep 1995 13:28:25 -0500 Organization: SABRE Decision Technologies In article <43rqbh$cvs@decaxp.harvard.edu>, hunt@scws4.harvard.edu (Timothy Hunt) wrote: > I would like to know the best way to loop a quicktime movie. I can not > seem to find anything in NIM to loop automatically, so maybe my program > must restart the movie itself from the beginning when it is done? Tim, Try this: Boolean wantLooping = TRUE; MCDoAction(theController, mcActionActivate, NULL); MCDoAction(theController, mcActionSetLooping, &wantLooping); StartMovie(theMovie); This will work, but I'me having a problem with the play button on the controller. I have to click it twice to get the movie to stop playing. If I click on the movie itself, it stops playing immediately. Maybe someone knows why? Hope this helps, Kelly tkmower@sdt.com -- T. Kelly Mower SABRE Decision Technologies tkmower@sdt.com +++++++++++++++++++++++++++ >From hunt@scws4.harvard.edu (Timothy Hunt) Date: 21 Sep 1995 18:28:00 GMT Organization: Harvard University, Cambridge, Massachusetts Andrew C. Plotkin (erkyrath+@CMU.EDU) wrote: : hunt@scws4.harvard.edu (Timothy Hunt) writes: : > I would like to know the best way to loop a quicktime movie. I can not : > seem to find anything in NIM to loop automatically, so maybe my program : > must restart the movie itself from the beginning when it is done? : > There is some references to looping in the TimeBase stuff - Does that : > contain the answer? : What I do is: : tb = GetMovieTimeBase(mov); : SetTimeBaseFlags(tb, loopTimeBase); So is the above all you need to do to get looping (ignoring smoothness)? Thanks again -Tim (hunt@fas.harvard.edu) +++++++++++++++++++++++++++ >From ldo@waikato.ac.nz (Lawrence D'Oliveiro) Date: Fri, 22 Sep 1995 18:20:48 +1200 Organization: University of Waikato In article <43rqbh$cvs@decaxp.harvard.edu>, hunt@scws4.harvard.edu (Timothy Hunt) wrote: >I would like to know the best way to loop a quicktime movie. I can not >seem to find anything in NIM to loop automatically, so maybe my program >must restart the movie itself from the beginning when it is done? >There is some references to looping in the TimeBase stuff - Does that >contain the answer? That is one answer. If your movie has a controller, then the controller is also able to provide another. >If that is the case, should I set up some kind of call back to notify me >when my movie has finished? Yes, this would be an answer as well. > Can I restart from such a call back which >would probably occur at interupt time? I believe you can choose whether your callback is triggered at interrupt or non-interrupt time. You certainly couldn't make most Movie Toolbox calls at interrupt time. >I've also heard that there is some bit that must be set to get smooth >looping. Any info here? I guess this must be the new hintsLoop bit added to the PlayHints in QuickTime 2.0. Odd--it's in my interface file, but I can't see it mentioned anywhere in this "QuickTime 2.0 Developer Guide for Macintosh" I have in front of me. --------------------------- >From kenlong@netcom.com (Ken Long) Subject: Novice Tech Tip #1 - SetRect. Date: Mon, 18 Sep 1995 15:24:26 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) While under development, you can save yourself a lot of aggravation, if you are setting many rectangles, by following a couple easy methods and using a couple indispensible utility. One utility is "MouseLoc F-Key" it's as "handy as a pocket on a shirt"(tm). It gives local and global mouse coodrdinates, as well as click one and click two coordinates. Of ALL the mouse location utilities, MouseLoc is the best one. (The other utility is CMaster.) MouseLoc F-Keys useful for determining where the coordinates are (or should be) for rectangles within your program windows. It's also great for determining MoveTo and LineTo coords. No need to fire up an additional program, or bring one to front to block your view. The tip I wanted to mention is that if you have several rectangles that have somthing to do with each other, are in the same area of your window, and possibly have one edge in alignment, it's easier, while under development, to base subsequent rectangles off a base of some sort, and then just use the original coords and add offset additions, rather than trying to dial in the exact coords. Then later, once the position is finalized, go back, with a calculator, and determine the exact coords and change them. For example, say you want 3 rects lined up horizontally, all the same size. SetRect (&rectOne, 20, 50, 75, 75); That's the first rect. What I do is tripple click to sellct the whole line, type Command C, and Command V *3 times*. Now I have: SetRect (&rectOne, 20, 50, 75, 75); SetRect (&rectOne, 20, 50, 75, 75); SetRect (&rectOne, 20, 50, 75, 75); Now I didn't have to retype for the other two rects. So I change the names next: SetRect (&rectOne, 20, 50, 75, 75); SetRect (&rectTwo, 20, 50, 75, 75); SetRect (&rectTri, 20, 50, 75, 75); Now, just add offsets on the horizontal and see how they look: SetRect (&rectOne, 20, 50, 75, 75); SetRect (&rectTwo, 20 + 60, 50, 75 + 60, 75); SetRect (&rectTri, 20 + 60 + 60, 50, 75 + 60 + 60, 75); After the first "+ 60+ of course I copied that and merely pasted it onto the other coodrds. Reduce typing at every opportunity. Can't see how they look? Either frame them temporarily, or "wash" them over a "dirty" background. Framing is the easiest. Copy all three lines (to save typing), and paste them in below the SetRect calls and delete the coords: SetRect (&rectOne); SetRect (&rectTwo); SetRect (&rectTri); Then change SetRect to FrameRect. Using CMaster, all you have to do is double-click the first "SetRect" and hit the down or up search icon (to get "SetRect" in the queue as the search string), type "FrameRect", double-click that, copy and deselect. Now click the down search icon and paste, click, paste, click paste - for as many SetRect calls you have to change. It's a snap! Once you get all your rectangles finalized for position, delete all the FrameRect calls and you're rolling. You can also go back ad add up the coords/offsets and type in the real value (I could have said "true value" but those are hardware items). MouseLoc F-Key, CMaster and QuicKeys are essential Think C programming tools - the last two for all around coding and the first one for graphics. The "wipe" over a "dirty" background refers to erasing the window (or painting it) with the lightest gray RGB, then erasing your rectangles after you set them, to see where they are. -Ken- +++++++++++++++++++++++++++ >From pottier@galion.ens.fr (Francois Pottier) Date: 19 Sep 1995 12:52:30 GMT Organization: Ecole Normale Superieure, Paris In article <kenlongDF3xGq.34M@netcom.com>, Ken Long <kenlong@netcom.com> wrote: > You can also go back ad add up the coords/offsets and type in the > real value You don't have to do that. The compiler should be smart enough to compute the expression for you at compile-time. This way, you can keep your code more readable and easier to change. -- Francois Pottier pottier@dmi.ens.fr - ---------------------------------------------------------------------------- Check my WWW page at http://acacia.ens.fr:8080/home/pottier/ ... +++++++++++++++++++++++++++ >From Scott Thompson <sthompson@macromedia.com> Date: 19 Sep 1995 14:16:06 GMT Organization: Macromedia As a side note, if you're calling SetRect many many times in a tight loop, you might also consider simply assigning each coordinate of the rect rather than calling SetRect (i.e. myRect.top = 12; myRect.left = 5+37, etc.) That way you avoid the overhead of the trap dispatcher. Scott Thompson +++++++++++++++++++++++++++ >From Carl R. Osterwald <carl_osterwald@nrel.gov> Date: 19 Sep 1995 15:32:05 GMT Organization: National Renewable Energy Laboratory In article <kenlongDF3xGq.34M@netcom.com> Ken Long, kenlong@netcom.com writes: >SetRect (&rectOne, 20, 50, 75, 75); >SetRect (&rectOne, 20, 50, 75, 75); >SetRect (&rectOne, 20, 50, 75, 75); When you have lots of Rects to deal with, another way to create them is it steal the 'nrct' resource that was originally created for control panels. It saves you from having to code each one, and the built-in TMPL allows editing outside of the source. The resource gives you an array for easy indexing: typedef struct { short no_of_rects; Rect nrcts[1]; } nrct; typedef nrct *nrctPtr, *nrctHandle; This is great way to handle baloon help manually. +++++++++++++++++++++++++++ >From A_student@postoffice.utas.edu.au (A Student) Date: Wed, 20 Sep 1995 13:30:11 +1100 Organization: University of Tasmania > One utility is "MouseLoc F-Key" it's as "handy as a pocket on a shirt"(tm). > It gives local and global mouse coodrdinates, as well as click one and > click two coordinates. Of ALL the mouse location utilities, MouseLoc is > the best one. (The other utility is CMaster.) Great Novice Tech Tip #1 Ken but where can I get MouseLoc F-Key? I have looked through Info-Mac but cannot find it, I am assumming that it's a demo or shareware. So if you could pass on a ftp site or even post it in alt.source.mac it would be a great help. Keep up the good work, you are a great help to novices! JT :) --------------------------- >From tkkuyken@powergrid.electriciti.com (Tod K Kuykendall) Subject: Obscure FILEID question Date: 19 Sep 1995 23:57:48 GMT Organization: Stark Visual Images Howdy! I've torn apart IM:Files but I have a couple more questions about the FILE ID. I know it states that once a FILE ID is used it is never reassigned to another file - but is it possible to force write a file into a different ID? It is part of catalog node (I think) so you'd probably mung something if you tried to do this but does anyone know for sure. What if a file is deleted but you back it up off another media - the FILE ID gets reassigned - but could you force back into it's original ID or not? Is there another way to force (or influence the creation of a FILE ID number) to cause a file to reuse an ID? What if you brute force copy the sector off onto something else, delete the original and the write it back. What else would you have to notify/update to get the file noticed again? Any and all thoughts/theories/suggestions welcomed.... =tkk "I just want to say the sooner we get that filthy Rosanne off the air American TV will be better for it. PS I love Hard Copy." -viewer reaction on Hard Copy's 1-900 number response line +++++++++++++++++++++++++++ >From becker@Xenon.Stanford.EDU (Denizen of the Deep) Date: 20 Sep 1995 01:22:57 GMT Organization: Computer Science Department, Stanford University. In article <43nlds$qsi@watt.electriciti.com>, Tod K Kuykendall <tkkuyken@powergrid.electriciti.com> wrote: > > >Howdy! > > I've torn apart IM:Files but I have a couple more questions about the >FILE ID. > I know it states that once a FILE ID is used it is never reassigned >to another file - but is it possible to force write a file into a >different ID? It is part of catalog node (I think) so you'd probably >mung something if you tried to do this but does anyone know for sure. >What if a file is deleted but you back it up off another media - the >FILE ID gets reassigned - but could you force back into it's original >ID or not? What I'm about to say is NOT RECOMMENDED, but since you asked I'll give you the story. It is possible to force a newly created file or directory to have some arbitrary file ID (as long as it's not one of the reserved IDs mentioned in IM:Files). The way the File Manager tries to ensure the uniqueness of IDs on a particular volume is by keeping a number around which represents the ID for the next created file/folder. It simply increments with every file or folder creation. The number is a 32-bit value, so if you ever created more than about 4 billion files/folders over the course of a volume's life, there could be problems (regardless of whether or not you throw some of those files away). This value is stored in the MDB on disk and in the VCB in memory (it's called vcbNxtCNID). You can retrieve it with a call to PBHGetVInfo. Its value is ignored in a call to PBHSetVInfo, so you can't set it that way. You can, however, walk the VCB queue in memory and manually set the value of this number in the desired volume's VCB to some arbitrary value. The next file or folder you create will then be given an ID equal to the value you chose. If another file or folder on the volume already has this value, then probably some Bad Things (tm) would occur. Well, now that you know how it's done, don't do it! :-) -Jon --------------------------- >From drysdall@waikato.ac.nz (Richard Drysdall) Subject: Q: FindFolder won't link Date: Wed, 13 Sep 1995 10:42:11 +1200 Organization: University of Waikato I'm trying to use FindFolder in my Mac application (compiled with Think C 7.0.4). The compiler always complains that link failed: undefined "FindFolder", even though I've included <Folders.h>. Any suggestions? Thanks (sorry this is so short - OT problems!). -- Richard Drysdall University of Waikato New Zealand "I'm called a theoretical physicist because in practice I'm not." +++++++++++++++++++++++++++ >From tim@dierks.org (Tim Dierks) Date: Tue, 12 Sep 1995 23:37:46 +0100 Organization: Best Internet Communications In article <drysdall-1309951042110001@plasma4.phys.waikato.ac.nz>, drysdall@waikato.ac.nz wrote: >I'm trying to use FindFolder in my Mac application (compiled with Think C >7.0.4). The compiler always complains that link failed: undefined >"FindFolder", even though I've included <Folders.h>. Any suggestions? Either: - Add the library "MacTraps2" to add the FindFolder glue or - #define SystemSevenOrLater to 1 before including <Folders.h> (assuming that you can in fact assume you're running under System 7). Enjoy, - Tim -- Tim Dierks tim@dierks.org +++++++++++++++++++++++++++ >From axlrosen@tiac.net (Alex Rosen) Date: Sat, 16 Sep 1995 14:43:58 -0500 Organization: The Internet Access Company In article <tim-1209952337460001@tdierks.vip.best.com>, tim@dierks.org (Tim Dierks) wrote: >In article <drysdall-1309951042110001@plasma4.phys.waikato.ac.nz>, >drysdall@waikato.ac.nz wrote: > >>I'm trying to use FindFolder in my Mac application (compiled with Think C >>7.0.4). The compiler always complains that link failed: undefined >>"FindFolder", even though I've included <Folders.h>. Any suggestions? > >Either: > - Add the library "MacTraps2" to add the FindFolder glue > or > - #define SystemSevenOrLater to 1 before including <Folders.h> > (assuming that you can in fact assume you're running under System 7). To be a little more specific: In Think C (and I think in all dev environments), FindFolder is implemented in glue that allows it to work with System 6, even though the trap only exists in System 7. This glue is in MacTraps2 in Think C. If the user is running System 6, it uses other system calls to point you to the System folder for all requests (since the Extensions, Preferences, etc folders don't exist before System 7). If the user is running under System 7 or later, it simply calls through to the real FindFolder. If you #define SystemSevenOrLater, you're telling Folders.h that you don't need the glue since you won't be running under systems earlier than 7. (Or you'll check the system version yourself and do the right thing, rather than using the glue.) --Alex --------------------------- >From becker@Xenon.Stanford.EDU (Denizen of the Deep) Subject: Resource size limits? Date: 14 Sep 1995 18:45:50 GMT Organization: Computer Science Department, Stanford University. I seem to recall that there are some built-in limits on the sizes of resources (number of bits in offset field, that sort of thing). I think that there is a limit on the size of an individual resource, as well as on the total size of all resources in a file. Can anybody point me to some documentation on this? I couldn't find anything about it in the Resources chapter of IM: More Mac Toolbox. :-( -Jon +++++++++++++++++++++++++++ >From jjohnson@crl.com (Jeffrey Johnson) Date: 14 Sep 1995 22:35:30 GMT Organization: CRL Dialup Internet Access (415) 705-6060 [Login: guest] Denizen of the Deep (becker@Xenon.Stanford.EDU) wrote: : : I seem to recall that there are some built-in limits on the sizes : of resources (number of bits in offset field, that sort of thing). : I think that there is a limit on the size of an individual resource, : as well as on the total size of all resources in a file. : : Can anybody point me to some documentation on this? I couldn't : find anything about it in the Resources chapter of IM: More Mac : Toolbox. :-( TB555 tech note says there is a limit of 2727 resources in a file and that a resource may be up to MAXLONGINT bytes- but from painful experience and from a previous plea for info, it looks like you can only have a resource fork < 16MB. Sigh... Thanks Jeff -- Jeffrey Johnson jjohnson@crl.com If you believe what you read, the sky is thick with aliens who are designing pyramids, disemboweling livestock, impregnating rural people and generally having a good time at our expense. -Scott Adams +++++++++++++++++++++++++++ >From resorcerer@aol.com (Resorcerer) Date: 15 Sep 1995 04:27:47 -0400 Organization: America Online, Inc. (1-800-827-6364) Jon - There is a limit of 2727 resources total in a resource file, due to a crazy calculation involving 16-bit offsets, blah, blah. In addition, the total size of the file is limited to 16MB, due to computations only being done in 24-bit offsets (or some such thing). Also, you generally don't want more than, say, 500 resources (Your Mileage May Vary) of any one type, because the resource manager has to traverse the entire list to get to the end. The only other thing that comes to mind is the fact that Rez computes all offsets in bits, not bytes, so if it's keeping all its numbers in longs, then 16MB is the largest size (in bytes) in can handle. I don't know if this is the case (not being a Rez user), but it's a thought. Doug McKenna Mathemaesthetics, Inc. Developers of Resorcerer +++++++++++++++++++++++++++ >From becker@Xenon.Stanford.EDU (Denizen of the Deep) Date: 15 Sep 1995 15:48:49 GMT Organization: Computer Science Department, Stanford University. In article <43bde3$8h2@newsbf02.news.aol.com>, Resorcerer <resorcerer@aol.com> wrote: >Jon - > >There is a limit of 2727 resources total in a resource file, due to a >crazy calculation involving 16-bit offsets, blah, blah. In addition, the >total size of the file is limited to 16MB, due to computations only being >done in 24-bit offsets (or some such thing). Also, you generally don't >want more than, say, 500 resources (Your Mileage May Vary) of any one >type, because the resource manager has to traverse the entire list to get >to the end. Yeah, the 16MB limit jibes well with the fact that there are 3 bytes in the resource map for a resource's offset from the beginning of the data (this suggests to me that the cumulative resource data can't be more than 16MB, not that the whole file can't be). I don't quite see where the 2727 comes from. But regardless, what I was really looking for was some official documentation on this stuff. Is there any? > >The only other thing that comes to mind is the fact that Rez computes all >offsets in bits, not bytes, so if it's keeping all its numbers in longs, >then 16MB is the largest size (in bytes) in can handle. I don't know if >this is the case (not being a Rez user), but it's a thought. Hmm, 2^32 bits would be 512 MB as far as I can tell... :-) > >Doug McKenna Thanks for your help, Doug. -Jon +++++++++++++++++++++++++++ >From andrewwelc@aol.com (AndrewWelc) Date: 15 Sep 1995 21:03:40 -0400 Organization: America Online, Inc. (1-800-827-6364) > But regardless, what I was really looking for was some official > documentation on this stuff. Is there any? Yes -- there was a tech note years ago called "Don't abuse the managers". Check Apple's ftp or web site. Regards, Andrew Welch Thaumaturgist Ambrosia Software, Inc. .......... For the latest versions of our software, technical support, and Ambrosia news, stop by and visit the Ambrosia Software, Inc. support forums: America Online ---> Keyword: Ambrosia CompuServe ---> GO word: Ambrosia eWorld --> Shortcut: Ambrosia +++++++++++++++++++++++++++ >From ckt@best.com (Chris Thomas) Date: Sat, 16 Sep 1995 04:34:16 -0800 Organization: Echo Software In article <43bde3$8h2@newsbf02.news.aol.com>, resorcerer@aol.com (Resorcerer) wrote: > Jon - > > There is a limit of 2727 resources total in a resource file, due to a > crazy calculation involving 16-bit offsets, blah, blah. In addition, the > total size of the file is limited to 16MB, due to computations only being > done in 24-bit offsets (or some such thing). Also, you generally don't > want more than, say, 500 resources (Your Mileage May Vary) of any one > type, because the resource manager has to traverse the entire list to get > to the end. $64.00 Q: What, if any, of this changed with the new Native Resource Manager? -- Chris Thomas, ckt@best.com +++++++++++++++++++++++++++ >From tim@dierks.org (Tim Dierks) Date: Sat, 16 Sep 1995 13:21:46 +0100 Organization: Best Internet Communications In article <ckt-1609950434160001@ckt.vip.best.com>, ckt@best.com (Chris Thomas) wrote: >In article <43bde3$8h2@newsbf02.news.aol.com>, resorcerer@aol.com >(Resorcerer) wrote: >> [ Various resource manager limitiations ] >$64.00 Q: What, if any, of this changed with the new Native Resource >Manager? Probably none of it, since these are all map-format limitations, and the map didn't change in the port to native. - Tim -- Tim Dierks tim@dierks.org --------------------------- >From Bill Rose Subject: [Q] MPW and printf()...Again Date: 22 Sep 1995 14:47:19 GMT Organization: NIST/ASD/SNLP In article <43s0a3$oul@seaman.cc.purdue.edu>, ags@seaman.cc.purdue.edu (Dave Seaman) writes: > > It's because of the way MPW does input. Your code will work if you add > a newline at the end of your prompt: > > printf("Please enter the name of the file to convert>\n"); > scanf("%s", &in_name); > inp = fopen(in_name, "r"); > > The reason is that when you press <enter> to send a line of text in > MPW, your program sees the entire line (including the "Please ..." > prompt). Putting your response on a spearate line is the easy way to > solve the problem. Otherwise, you would need to have your program > recognize and skip over the prompt. > > Dave Seaman To all who answered this: First thanks a lot for the input. I should have mentioned this before, but I had tried the \n and it still didn't work right. However, the code without the \r was compiled to a SIOW and it did work. I guess that I'll have to fool with it more to see if I'm messing up somewhere else and try to get it to work on the command line, but I don't think MPW is necessarily friendly with the command line programming or else I simply have to get used to doing things with the new line command in my printf() statements from now on. Again, thanks for your help. Bill Rose wrose@nist.gov +++++++++++++++++++++++++++ >From gregb@genmagic.com (Greg Branche) Date: Fri, 22 Sep 1995 21:19:55 -0700 Organization: General Magic In article <43ui9n$qm0@dove.nist.gov>, billr@jaguar.ncsl.nist.gov wrote: >First thanks a lot for the input. I should have mentioned this before, but I >had tried the \n and it still didn't work right. However, the code without the >\r was compiled to a SIOW and it did work. I just thought of another factor in this problem. When entering the text in response to the prompt, did you press the <Return> key to terminate the input, or did you press the <Enter> key? MPW maintains a distinction between the two, since the "command line" in the worksheet can be viewed as just another line in the document that is being edited. (After all, MPW is just a text editor with a few minor additions. :-) The proper method is to use the <Enter> key to terminate the response. This is a signal to the shell that the line containing the cursor is to be processed as stdin. Greg Branche Magic Cap Entomologist General Magic, Inc. --------------------------- >From reed@medicine.wustl.edu (Thomas Reed) Subject: how do I get char minus any modifier key alterations? Date: Mon, 18 Sep 1995 16:39:53 -0500 Organization: Washington University I need to capture and display a user's keypress. For instance, if the user presses cmd-opt-p, I want to display "Command + Option + p". Unfortunately, when I get the key pressed from the EventRecord, it is the MODIFIED key -- for instance, the character from the above keypress would be pi. This is obviously not what I want -- I don't want to display "Command + Option + pi"! So... is there any way that I can modify this character to get the raw character rather than the modified character? Thanks in advance! -Thomas ===================================================== Thomas Reed Washington University reed@visar.wustl.edu Medical School reed@medicine.wustl.edu Saint Louis, MO http://medinfo.wustl.edu/~reed - --------------------------------------------------- Clothes make the man. Naked people have little or no influence on society. -- Mark Twain ===================================================== Opinions posted are not the opinions of Wash. U. +++++++++++++++++++++++++++ >From grobbins@znet.com (Grobbins) Date: Mon, 18 Sep 1995 18:33:37 -0700 Organization: Skunkworks In article <reed-1809951639530001@thomasmac.wustl.edu>, reed@medicine.wustl.edu (Thomas Reed) wrote: >So... is there any way that I can modify this character to get the raw >character rather than the modified character? Take the virtual keyCode and reprocess it with KeyTrans. The technique is discussed in tech note TE 515 (Keyboard Resource Q&A's); the appropriate section of that note is pasted below. Be aware that the identifier names used in the tech note Q&A are archaic; look in the OLDROUTINENAMES section of the current headers for the new names. Grobbins grobbins@znet.com -------------- Macintosh Option key: Techniques for ignoring Date Written: 10/16/91 Last reviewed: 2/28/92 I would like to use the Macintosh Option key as the Control key for keyboards that lack a Control key, such as for Macintosh Plus keyboards. How can I find the ASCII value that would have been returned if the Option key weren’t pressed, in a way that would be compatible with other keyboards? ___ There are a couple of clean ways to ignore the Option key. One is to “reprocess” the keyboard event. The fourth byte of the event message is the ASCII code, but the third byte is the virtual key code. The system calls the trap KeyTrans to map the virtual key code to ASCII according to a 'KCHR' resource. You can do the same, and since the high byte of the modifiers are part of the input to KeyTrans, you can strip out the Option key, call KeyTrans on the third byte of the event message, and get back the “true” ASCII keypress. KeyTrans and 'KCHR' resources are documented in Chapter 10 of Inside Macintosh Volume V, Chapter 14 of Inside Macintosh Volume VI (pages 14-23 and 14-96), and the Macintosh Technical Note “Key Mapping.” In Pascal, these steps would look something like: keycode := BAND(event.message, keyCodeMask); { get virtual code } keycode := BSR(keycode, 8); { move to low byte } { now combine with modifiers } keycode := BOR(keycode, BAND($FF00, event.modifiers)); keycode := BAND(keycode, $FFFF - optionKey); { strip option } newkey := KeyTrans(KCHRHandle^, keyCode, state); The resource ID of the current KCHR is available as GetScript(GetEnvirons(smKeyScript), smScriptKeys). Alternatively, a pointer to the KCHR data is available under System 7 as GetEnvirons(smKCHRCache), as discussed in the Tech Note “International Canceling.” This method may work for you, but there is a possible problem: dead keys. Since dead keys are processed before your application gets the event, your application will not see (for example) the first Option-e typed. However, the dead keys are specified in the 'KCHR' resource, so you can create a KCHR (ResEdit 2.1.1 includes a template) to omit dead keys (and, if you choose, option characters) and include it with your application. Call SetScript to get the system to use your 'KCHR' (see the Tech Note “Key Mapping,” IM V-313, and IM VI 14-40). Another problem is that System 7 ignores a 'KCHR' in the application’s resources, so an application’s 'KCHR' has to be installed in the system. You can install the 'KCHR' with an installer program, or provide a keyboard file users can drag to the System file. (To create a keyboard file, use ResEdit to put the 'KCHR' in the System file, and then drag it out with the System 7 Finder.) +++++++++++++++++++++++++++ >From Richard Kennaway <jrk@sys.uea.ac.uk> Date: 19 Sep 1995 11:50:48 GMT Organization: SYS, University of East Anglia In article <reed-1809951639530001@thomasmac.wustl.edu> Thomas Reed, reed@medicine.wustl.edu writes: >So... is there any way that I can modify this character to get the raw >character rather than the modified character? For the application you describe, what you want is a mapping from the keycode to what is actually drawn on the keycap, but I don't know of any way of getting that (in a manner that will deal well with e.g. all the keys on the extended keyboard). Is there any sort of keyboard definition resource in the System? To find the unmodified character code, this is what I did in code written a few years ago (using MPW C and System 6). Maybe there's a simpler way now? 1. Take the keyCode from the event record. Set the upper byte (the modifiers byte) to 0. 2. Get the relevant KCHR resource (see below). 3. Pass these to KeyTranslate to find out what the character code would have been if no modifier keys had been pressed. 4. KeyTranslate returns a 4-byte result, of which the character code could be either the least significant or the third-least significant, so you get the character code by: charCode = (((result >> 16)==0) ? result : (result >> 16)) & 255; It is possible for both of those bytes to be non-zero in some script systems, in which a keystroke can generate a pair of characters. Remember to lock the resource handle before KeyTranslate and to restore its state after, since KeyTranslate takes a pointer to the KCHR data, not a handle. How do you find the right KCHR resource? To be compatible with all versions of the system software: 1. Test if the Script Manager is present. 2. If it is, get the KCHR resource like so: sysKCHRId = GetScript( GetEnvirons( smSystemScript ), smScriptKeys ); sysKCHRHandle = GetResource( 'KCHR', (int16) sysKCHRId ); ("int16" = 2-byte integer type.) I'm not absolutely sure that smSystemScript would be correct for you. I use this code when processing menu command-keys, so I want to use the script id relevant to drawing menus. For your application, what you want is the script most likely to represent what is drawn on the key caps, and unless you have a very fancy keyboard, that doesn't change when you change scripts. 3. If the Script Manager is absent, or if the above code leaves you with a nil sysKCHRHandle, try to get the resource id from the "international" resource: if ((itl0 = (Intl0Hndl) IUGetIntl( 0 )) != nil) { sysKCHRId = (((**itl0).intl0Vers) >> 8) & 255; sysKCHRHandle = GetResource( 'KCHR', (int16) sysKCHRId ); } 4. If that doesn't work, then as a last resort, try: sysKCHRId = 0; sysKCHRHandle = GetResource( 'KCHR', (int16) sysKCHRId ); It still works for me, but I don't know which branches of the KCHR-finding code have ever been executed. I've also never run it on any machine having exotic script systems. I can email the relevant code in its working form if anyone wants it. ___ \X/ Richard Kennaway, jrk@sys.uea.ac.uk, http://www.sys.uea.ac.uk/~jrk/ School of Information Systems, Univ. of East Anglia, Norwich +++++++++++++++++++++++++++ >From PaulS101@mailbox.ioa.com (Paul Sexton) Date: 20 Sep 1995 16:40:32 GMT Organization: Vnet Internet Access, Charlotte, NC - info@char.vnet.net In article <reed-1809951639530001@thomasmac.wustl.edu>, reed@medicine.wustl.edu (Thomas Reed) wrote: > I need to capture and display a user's keypress. For instance, if the > > So... is there any way that I can modify this character to get the raw > character rather than the modified character? > /* Written in CW6 c++, modified slightly. Based on code by: grobbins@zNET.com (Grobbins) Function converts inMacEvent.message (the key) as though NO modifiers were down, leaves inMacEvent.modifiers alone so you can get at it. NO allowance for multi-key characters (option sequences): you're on your own there. I use this to implement keyboard equivalents that contain modifiers other than Command. (All letters delivered in lower case: check shiftKey bit). I highly recommend that you read up on KeyTranslate() - nothing here is hard except getting kchrResPtr. */ #include <Events.h> #include <Script.h> // Locals - set up here and then leave alone // breaking kchrResPtr into 2 parts and putting in constructor saves a few bytes static UInt32 state = 0; static Ptr kchrResPtr = *::RGetResource('KCHR',::GetScriptVariable(::GetScriptManagerVariable(smKeyScript), smScriptKeys)); static void StripModifiers(EventRecord &inMacEvent); void StripModifiers(EventRecord &inMacEvent) { // Look up KeyTranslate() for the key to this: virtual keycode in low byte, // modifiers (0) in upper. Assumes this is a key DOWN event. short modKeyCode = (inMacEvent.message & keyCodeMask) >> 8; modKeyCode = ::KeyTranslate(kchrResPtr,modKeyCode,&state); inMacEvent.message = (inMacEvent.message & ~charCodeMask) | (modKeyCode & charCodeMask); } +++++++++++++++++++++++++++ >From rdwells@mmm.com (Richard Wells) Date: 20 Sep 1995 15:05:14 GMT Organization: 3M Company reed@medicine.wustl.edu (Thomas Reed) wrote: >I need to capture and display a user's keypress. For instance, if the >user presses cmd-opt-p, I want to display "Command + Option + p". >Unfortunately, when I get the key pressed from the EventRecord, it is the >MODIFIED key -- for instance, the character from the above keypress would >be pi. This is obviously not what I want -- I don't want to display >"Command + Option + pi"! > >So... is there any way that I can modify this character to get the raw >character rather than the modified character? Unless I misunderstand you, the information you need is contained in the event record. The 'message' field contains the virtual key code as well as the character it translates to. _Inside Macintosh: Macintosh Toolbox Essentials_ contains pictures of which keys on various keyboards generate which virtual key codes. +++++++++++++++++++++++++++ >From munz@wordperfect.com (Mark Munz) Date: Fri, 22 Sep 1995 08:40:38 -0600 Organization: Novell, Inc. In article <43paja$l43@dawn.mmm.com>, rdwells@mmm.com (Richard Wells) wrote: > >So... is there any way that I can modify this character to get the raw > >character rather than the modified character? > > Unless I misunderstand you, the information you need is contained > in the event record. The 'message' field contains the virtual key > code as well as the character it translates to. > > _Inside Macintosh: Macintosh Toolbox Essentials_ contains pictures > of which keys on various keyboards generate which virtual key codes. One note, if you use the Event Manager, you'll have to watch for dead-key issues. An app never sees the first dead-key hit (opt-N). You'll either have to setup your own Keyboard resource, or use something like GetKeys to grab info from the keyboard. Mark Munz --------------------------- End of C.S.M.P. Digest **********************